Merge branch 'develop' into feature/sdl2

This commit is contained in:
filux
2015-11-05 20:44:00 +01:00
305 changed files with 817 additions and 98451 deletions

1
.gitignore vendored
View File

@@ -39,6 +39,7 @@ $RECYCLE.BIN/
*.tar *.tar
*.zip *.zip
*.bz2 *.bz2
*.tar.xz
## Logs and databases ## Logs and databases
*.log *.log

3
.gitmodules vendored
View File

@@ -4,3 +4,6 @@
[submodule "source/masterserver"] [submodule "source/masterserver"]
path = source/masterserver path = source/masterserver
url = https://github.com/MegaGlest/megaglest-masterserver.git url = https://github.com/MegaGlest/megaglest-masterserver.git
[submodule "mk/linux/tools-for-standalone-client/installer/mojosetup"]
path = mk/linux/tools-for-standalone-client/installer/mojosetup
url = https://github.com/MegaGlest-Community/mojosetup-fork.git

View File

@@ -8,10 +8,15 @@ PROJECT( MegaGlest )
# VC++ users should not use CMake yet but rather the build-mg.bat file in mk/windoze # VC++ users should not use CMake yet but rather the build-mg.bat file in mk/windoze
# #
# build type defaults to release # build type
if(NOT DEFINED CMAKE_BUILD_TYPE) IF(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose build type: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") SET(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose build type: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE)
endif(NOT DEFINED CMAKE_BUILD_TYPE) ENDIF()
SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS None Debug Release RelWithDebInfo MinSizeRel)
IF(NOT CMAKE_VERSION VERSION_LESS "3.1")
cmake_policy(SET CMP0054 NEW)
ENDIF()
# add additional CMake modules # add additional CMake modules
MESSAGE(STATUS "CMAKE_SOURCE_DIR = ${CMAKE_SOURCE_DIR}") MESSAGE(STATUS "CMAKE_SOURCE_DIR = ${CMAKE_SOURCE_DIR}")
@@ -30,8 +35,14 @@ OPTION(BUILD_MEGAGLEST_MODEL_VIEWER "Build model viewer" ON)
OPTION(BUILD_MEGAGLEST_MAP_EDITOR "Build map editor" ON) OPTION(BUILD_MEGAGLEST_MAP_EDITOR "Build map editor" ON)
OPTION(BUILD_MEGAGLEST "Build MegaGlest" ON) OPTION(BUILD_MEGAGLEST "Build MegaGlest" ON)
OPTION(BUILD_MEGAGLEST_TESTS "Build MegaGlest Unit Tests" OFF) OPTION(BUILD_MEGAGLEST_TESTS "Build MegaGlest Unit Tests" OFF)
OPTION(WITH_VLC "Use libVLC to play videos" ON) OPTION(WANT_SINGLE_INSTALL_DIRECTORY "Use single install directory for everything. It is useful for example for MacOS cpack bundles." OFF)
OPTION(SINGLE_INSTALL_DIRECTORY "Use single install directory for everything. It is useful for example for MacOS cpack bundles." OFF) OPTION(WANT_STATIC_LIBS "Builds as many static libs as possible." OFF)
OPTION(WANT_USE_VLC "Use libVLC to play videos." ON)
OPTION(WANT_USE_OpenSSL "Use libOpenSSL during CURL linking." ON)
OPTION(WANT_USE_FriBiDi "Enable libFriBIDi support." ON)
OPTION(WANT_USE_GoogleBreakpad "Enable GoogleBreakpad support." ON)
OPTION(WANT_USE_STREFLOP "Use the library streflop." ON)
OPTION(WANT_USE_XercesC "Enable libXercesC support." OFF)
FIND_PROGRAM(HELP2MAN "help2man") FIND_PROGRAM(HELP2MAN "help2man")
@@ -41,8 +52,10 @@ if (NOT ${XVFB_RUN} MATCHES "XVFB_RUN-NOTFOUND")
set(XVFB_EXEC ${XVFB_RUN}) set(XVFB_EXEC ${XVFB_RUN})
message(STATUS "Using xvfb-run to run man2help.") message(STATUS "Using xvfb-run to run man2help.")
endif() endif()
MARK_AS_ADVANCED(HELP2MAN XVFB_RUN)
include(${CMAKE_SOURCE_DIR}/mk/cmake/Modules/SpecialMacros.cmake) include(${CMAKE_SOURCE_DIR}/mk/cmake/Modules/SpecialMacros.cmake)
include(${CMAKE_SOURCE_DIR}/mk/cmake/Modules/ReqVersAndStaticConf.cmake)
SET(PKG_NAME "megaglest") SET(PKG_NAME "megaglest")
# read version # read version
@@ -96,13 +109,6 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW)
MESSAGE(STATUS "Detected MINGW Compiler...") MESSAGE(STATUS "Detected MINGW Compiler...")
ENDIF() ENDIF()
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
# Default compiler flags
#SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s") ## Strip binary
# Common generic GNU type compiler options that work with all generic GCC compatible compilers # Common generic GNU type compiler options that work with all generic GCC compatible compilers
ADD_DEFINITIONS("-Wuninitialized -Wsign-compare -Wunused-function -Wunused-variable -Wreturn-type -fno-strict-aliasing") ADD_DEFINITIONS("-Wuninitialized -Wsign-compare -Wunused-function -Wunused-variable -Wreturn-type -fno-strict-aliasing")
@@ -133,34 +139,30 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW)
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
#MESSAGE(STATUS "*TEST: Checking for max SSE LEVEL [${MAX_SSE_LEVEL_DESIRED}]") #MESSAGE(STATUS "*TEST: Checking for max SSE LEVEL [${FORCE_MAX_SSE_LEVEL}]")
IF(NOT STREFLOP_SOFTWRAPPER_FORCE) OPTION(FORCE_STREFLOP_SOFTWRAPPER "Set the streflop library to be forced to use the software emulator" OFF)
SET(STREFLOP_SOFTWRAPPER_FORCE "0" CACHE STRING "Set the streflop library to be forced to use the software emulator") IF(NOT FORCE_MAX_SSE_LEVEL AND NOT FORCE_STREFLOP_SOFTWRAPPER)
SET(FORCE_MAX_SSE_LEVEL "1" CACHE STRING "Set the max SSE level to use if supported (0-3)")
ENDIF() ENDIF()
IF(NOT MAX_SSE_LEVEL_DESIRED AND NOT STREFLOP_SOFTWRAPPER_FORCE) IF(NOT FORCE_STREFLOP_SOFTWRAPPER)
SET(MAX_SSE_LEVEL_DESIRED "1" CACHE STRING "Set the max SSE level to use if supported (0-3)") MESSAGE(STATUS "*NOTE: Checking for max SSE LEVEL [${FORCE_MAX_SSE_LEVEL}]")
special_check_for_sse( ${FORCE_MAX_SSE_LEVEL} )
ENDIF() ENDIF()
IF(NOT STREFLOP_SOFTWRAPPER_FORCE) IF(WANT_USE_STREFLOP)
MESSAGE(STATUS "*NOTE: Checking for max SSE LEVEL [${MAX_SSE_LEVEL_DESIRED}]")
special_check_for_sse( ${MAX_SSE_LEVEL_DESIRED} )
ENDIF()
OPTION(WANT_STREFLOP "use the library streflop" ON)
IF(WANT_STREFLOP)
ADD_DEFINITIONS("-DUSE_STREFLOP -DSTREFLOP_RANDOM_GEN_SIZE=32 -DLIBM_COMPILING_FLT32 -DN_SPECIALIZED=32") ADD_DEFINITIONS("-DUSE_STREFLOP -DSTREFLOP_RANDOM_GEN_SIZE=32 -DLIBM_COMPILING_FLT32 -DN_SPECIALIZED=32")
IF(HAS_SSE_EXTENSIONS AND NOT ${MAX_SSE_LEVEL_DESIRED} MATCHES "0" AND NOT STREFLOP_SOFTWRAPPER_FORCE) IF(HAS_SSE_EXTENSIONS AND NOT ${FORCE_MAX_SSE_LEVEL} MATCHES "0" AND NOT FORCE_STREFLOP_SOFTWRAPPER)
ADD_DEFINITIONS("-DSTREFLOP_SSE") ADD_DEFINITIONS("-DSTREFLOP_SSE")
MESSAGE(STATUS "*NOTE: using SSE for STREFLOP.") MESSAGE(STATUS "*NOTE: using SSE for STREFLOP.")
ELSE() ELSE()
IF(NOT STREFLOP_SOFTWRAPPER_FORCE) IF(NOT FORCE_STREFLOP_SOFTWRAPPER)
special_check_for_x87() special_check_for_x87()
ENDIF() ENDIF()
IF(HAS_X87_SUPPORT AND NOT STREFLOP_SOFTWRAPPER_FORCE) IF(HAS_X87_SUPPORT AND NOT FORCE_STREFLOP_SOFTWRAPPER)
ADD_DEFINITIONS("-DSTREFLOP_X87") ADD_DEFINITIONS("-DSTREFLOP_X87")
MESSAGE(STATUS "*NOTE: using X87 for STREFLOP.") MESSAGE(STATUS "*NOTE: using X87 for STREFLOP.")
ELSE() ELSE()
@@ -200,9 +202,7 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW)
# Release compiler flags # Release compiler flags
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 ${CMAKE_CXX_FLAGS_RELEASE} -O3 ") SET(CMAKE_CXX_FLAGS_RELEASE "-O3 ${CMAKE_CXX_FLAGS_RELEASE} -O3 ")
IF(CMAKE_GENERATOR STREQUAL Xcode) IF(NOT CMAKE_GENERATOR STREQUAL Xcode)
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") ## Strip binary
ELSE()
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s") ## Strip binary SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s") ## Strip binary
ENDIF() ENDIF()
@@ -211,11 +211,8 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW)
# Release minimum size compiler flags # Release minimum size compiler flags
SET(CMAKE_CXX_FLAGS_MINSIZEREL "-O3 ${CMAKE_CXX_FLAGS_MINSIZEREL} -O3 ") SET(CMAKE_CXX_FLAGS_MINSIZEREL "-O3 ${CMAKE_CXX_FLAGS_MINSIZEREL} -O3 ")
SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}") ## Strip binary IF(NOT CMAKE_GENERATOR STREQUAL Xcode)
IF(CMAKE_GENERATOR STREQUAL Xcode) SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} -s") ## Strip binary
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") ## Strip binary
ELSE()
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s") ## Strip binary
ENDIF() ENDIF()
# Get the git revision info for the binary # Get the git revision info for the binary
@@ -263,45 +260,33 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW)
IF(CMAKE_INSTALL_PREFIX STREQUAL "") IF(CMAKE_INSTALL_PREFIX STREQUAL "")
MESSAGE(STATUS "*NOTE: NOT USING a Custom Data Install Path...") MESSAGE(STATUS "*NOTE: NOT USING a Custom Data Install Path...")
ELSE() ELSE()
IF(SINGLE_INSTALL_DIRECTORY AND NOT MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH) IF(WANT_SINGLE_INSTALL_DIRECTORY AND NOT MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH)
SET(MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH "megaglest-game/" CACHE STRING "The single directory installation path for game (this is appended to the CMAKE_INSTALL_PREFIX)") SET(MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH "megaglest-game/" CACHE STRING "The single directory installation path for game (this is appended to the CMAKE_INSTALL_PREFIX)")
ENDIF() ENDIF()
IF(NOT MEGAGLEST_BIN_INSTALL_PATH) IF(NOT MEGAGLEST_BIN_INSTALL_PATH AND NOT WANT_SINGLE_INSTALL_DIRECTORY)
IF(NOT SINGLE_INSTALL_DIRECTORY) SET(MEGAGLEST_BIN_INSTALL_PATH "bin/" CACHE STRING "The installation path for binaries (this is appended to the CMAKE_INSTALL_PREFIX)")
SET(MEGAGLEST_BIN_INSTALL_PATH "bin/" CACHE STRING "The installation path for binaries (this is appended to the CMAKE_INSTALL_PREFIX)")
ELSE()
SET(MEGAGLEST_BIN_INSTALL_PATH "${MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH}")
ENDIF()
ENDIF() ENDIF()
IF(NOT MEGAGLEST_DATA_INSTALL_PATH) IF(NOT MEGAGLEST_DATA_INSTALL_PATH AND NOT WANT_SINGLE_INSTALL_DIRECTORY)
IF(NOT SINGLE_INSTALL_DIRECTORY) SET(MEGAGLEST_DATA_INSTALL_PATH "share/megaglest/" CACHE STRING "The installation path for data files (this is appended to the CMAKE_INSTALL_PREFIX)")
SET(MEGAGLEST_DATA_INSTALL_PATH "share/megaglest/" CACHE STRING "The installation path for data files (this is appended to the CMAKE_INSTALL_PREFIX)")
ELSE()
SET(MEGAGLEST_DATA_INSTALL_PATH "${MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH}")
ENDIF()
ENDIF() ENDIF()
IF(NOT MEGAGLEST_DESKTOP_INSTALL_PATH) IF(NOT MEGAGLEST_DESKTOP_INSTALL_PATH AND NOT WANT_SINGLE_INSTALL_DIRECTORY)
IF(NOT SINGLE_INSTALL_DIRECTORY) SET(MEGAGLEST_DESKTOP_INSTALL_PATH "share/applications/" CACHE STRING "The installation path for desktop files (this is appended to the CMAKE_INSTALL_PREFIX)")
SET(MEGAGLEST_DESKTOP_INSTALL_PATH "share/applications/" CACHE STRING "The installation path for desktop files (this is appended to the CMAKE_INSTALL_PREFIX)")
ELSE()
SET(MEGAGLEST_DESKTOP_INSTALL_PATH "${MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH}")
ENDIF()
ENDIF() ENDIF()
IF(NOT MEGAGLEST_ICON_INSTALL_PATH) IF(NOT MEGAGLEST_ICON_INSTALL_PATH AND NOT WANT_SINGLE_INSTALL_DIRECTORY)
IF(NOT SINGLE_INSTALL_DIRECTORY) SET(MEGAGLEST_ICON_INSTALL_PATH "share/pixmaps/" CACHE STRING "The installation path for icon files (this is appended to the CMAKE_INSTALL_PREFIX)")
SET(MEGAGLEST_ICON_INSTALL_PATH "share/pixmaps/" CACHE STRING "The installation path for icon files (this is appended to the CMAKE_INSTALL_PREFIX)")
ELSE()
SET(MEGAGLEST_ICON_INSTALL_PATH "${MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH}")
ENDIF()
ENDIF() ENDIF()
IF(NOT MEGAGLEST_MANPAGE_INSTALL_PATH AND NOT SINGLE_INSTALL_DIRECTORY) IF(NOT MEGAGLEST_MANPAGE_INSTALL_PATH AND NOT WANT_SINGLE_INSTALL_DIRECTORY)
IF(NOT SINGLE_INSTALL_DIRECTORY) SET(MEGAGLEST_MANPAGE_INSTALL_PATH "share/man/man6/" CACHE STRING "The installation path for manpage files (this is appended to the CMAKE_INSTALL_PREFIX)")
SET(MEGAGLEST_MANPAGE_INSTALL_PATH "share/man/man6/" CACHE STRING "The installation path for manpage files (this is appended to the CMAKE_INSTALL_PREFIX)")
ELSE()
SET(MEGAGLEST_MANPAGE_INSTALL_PATH "${MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH}")
ENDIF()
ENDIF() ENDIF()
IF(NOT CUSTOM_DATA_INSTALL_PATH AND NOT SINGLE_INSTALL_DIRECTORY) IF(WANT_SINGLE_INSTALL_DIRECTORY)
FOREACH(MG_PATH BIN DATA DESKTOP ICON)
IF(NOT MEGAGLEST_${MG_PATH}_INSTALL_PATH)
SET(MEGAGLEST_${MG_PATH}_INSTALL_PATH "${MEGAGLEST_SINGLE_DIRECTORY_INSTALL_PATH}")
ENDIF()
ENDFOREACH()
ENDIF()
IF(NOT CUSTOM_DATA_INSTALL_PATH AND NOT WANT_SINGLE_INSTALL_DIRECTORY)
SET(CUSTOM_DATA_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}/${MEGAGLEST_DATA_INSTALL_PATH}" CACHE STRING "The FULL installation path for data files (this is build automatically by combining CMAKE_INSTALL_PREFIX and MEGAGLEST_DATA_INSTALL_PATH)") SET(CUSTOM_DATA_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}/${MEGAGLEST_DATA_INSTALL_PATH}" CACHE STRING "The FULL installation path for data files (this is build automatically by combining CMAKE_INSTALL_PREFIX and MEGAGLEST_DATA_INSTALL_PATH)")
SET(CUSTOM_DATA_INSTALL_PATH_VALUE "-DCUSTOM_DATA_INSTALL_PATH=${CUSTOM_DATA_INSTALL_PATH}") SET(CUSTOM_DATA_INSTALL_PATH_VALUE "-DCUSTOM_DATA_INSTALL_PATH=${CUSTOM_DATA_INSTALL_PATH}")
ENDIF() ENDIF()
@@ -311,45 +296,21 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW)
MESSAGE(STATUS "*NOTE: Custom Data Install Path is [${CUSTOM_DATA_INSTALL_PATH}]") MESSAGE(STATUS "*NOTE: Custom Data Install Path is [${CUSTOM_DATA_INSTALL_PATH}]")
ENDIF() ENDIF()
string(TOUPPER "${CMAKE_BUILD_TYPE}" MG_BUILD_TYPE)
IF(HAS_GIT STREQUAL "TRUE") IF(HAS_GIT STREQUAL "TRUE")
SET(CMAKE_CXX_FLAGS_NONE "${CMAKE_CXX_FLAGS_NONE} ${GIT_VERSION_CMD}") SET(CMAKE_CXX_FLAGS_${MG_BUILD_TYPE} "${CMAKE_CXX_FLAGS_${MG_BUILD_TYPE}} ${GIT_VERSION_CMD}")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${GIT_VERSION_CMD}")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${GIT_VERSION_CMD}")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${GIT_VERSION_CMD}")
SET(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${GIT_VERSION_CMD}")
ENDIF() ENDIF()
SET(CMAKE_CXX_FLAGS_NONE "${CMAKE_CXX_FLAGS_NONE} ${CUSTOM_DATA_INSTALL_PATH_VALUE}") SET(CMAKE_CXX_FLAGS_${MG_BUILD_TYPE} "${CMAKE_CXX_FLAGS_${MG_BUILD_TYPE}} ${CUSTOM_DATA_INSTALL_PATH_VALUE}")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CUSTOM_DATA_INSTALL_PATH_VALUE}")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CUSTOM_DATA_INSTALL_PATH_VALUE}")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CUSTOM_DATA_INSTALL_PATH_VALUE}")
SET(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${CUSTOM_DATA_INSTALL_PATH_VALUE}")
# We do some funky character escaping to get the right stuff written out to # We do some funky character escaping to get the right stuff written out to
# the final Makefile so we get the GIT Global Revsion # # the final Makefile so we get the GIT Global Revsion #
string(REPLACE "'" "\"" CMAKE_CXX_FLAGS_NONE "${CMAKE_CXX_FLAGS_NONE}") string(REPLACE "'" "\"" CMAKE_CXX_FLAGS_${MG_BUILD_TYPE} "${CMAKE_CXX_FLAGS_${MG_BUILD_TYPE}}")
string(REPLACE "'" "\"" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "'" "\"" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
string(REPLACE "'" "\"" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
string(REPLACE "'" "\"" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
IF( CMAKE_BUILD_TYPE STREQUAL None ) message(STATUS "CMAKE_CXX_FLAGS_${MG_BUILD_TYPE}: ${CMAKE_CXX_FLAGS_${MG_BUILD_TYPE}}")
message("CMAKE_CXX_FLAGS_NONE: ${CMAKE_CXX_FLAGS_NONE}")
ELSEIF( CMAKE_BUILD_TYPE STREQUAL Debug )
message("CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}")
ELSEIF( CMAKE_BUILD_TYPE STREQUAL Release )
message("CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}")
ELSEIF( CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo )
message("CMAKE_CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
ELSEIF( CMAKE_BUILD_TYPE STREQUAL MinSizeRel )
message("CMAKE_CXX_FLAGS_MINSIZEREL: ${CMAKE_CXX_FLAGS_MINSIZEREL}")
ENDIF()
# Win32 specific Compiler Flags # Win32 specific Compiler Flags
IF(WIN32) IF(WIN32)
ADD_DEFINITIONS("-D_WINDOWS -D_WIN32 -D_STDCALL_SUPPORTED -D_M_IX86 -DXML_LIBRARY -D_LIB -DCURL_STATICLIB") ADD_DEFINITIONS("-D_WINDOWS -D_WIN32 -D_STDCALL_SUPPORTED -D_M_IX86 -DXML_LIBRARY -D_LIB -DCURL_STATICLIB")
ELSE()
ADD_DEFINITIONS("-DCURL_STATICLIB")
ENDIF() ENDIF()
ENDIF() ENDIF()
@@ -358,6 +319,9 @@ IF(UNIX AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
# We don't wanna see bug reports with deprecation warnings from OSes where game isn't # We don't wanna see bug reports with deprecation warnings from OSes where game isn't
# actively developed, and where usually those warnings can make "make log" completely unreadable. # actively developed, and where usually those warnings can make "make log" completely unreadable.
# Main targets are: bsd and macos # Main targets are: bsd and macos
MARK_AS_ADVANCED(CLEAR wxWidgets_CONFIG_EXECUTABLE)
# This variable may be sometimes necessary to set manually.
ELSE() ELSE()
OPTION(WANT_DEPRECATION_WARNINGS "Want to see warnings related with deprecated code parts." ON) OPTION(WANT_DEPRECATION_WARNINGS "Want to see warnings related with deprecated code parts." ON)
ENDIF() ENDIF()
@@ -366,18 +330,23 @@ IF(NOT WANT_DEPRECATION_WARNINGS)
ENDIF() ENDIF()
MARK_AS_ADVANCED(WANT_DEPRECATION_WARNINGS) MARK_AS_ADVANCED(WANT_DEPRECATION_WARNINGS)
OPTION(WANT_USE_SDL2 "Want to use SDL2 instead of SDL1.X. SDL2 is not officially supported yet." OFF) SET(WANT_USE_SDL2 ON)
IF(NOT WANT_USE_SDL2) IF(WANT_USE_SDL2)
SET(SDL_WINDOWS_DIR_DINC "SDL-1.2.x")
SET(SDL_VERSION_NAME "SDL")
SET(SDL_VERSION_SNAME "sdl")
ELSE()
SET(SDL_WINDOWS_DIR_DINC "SDL-2.0.x") SET(SDL_WINDOWS_DIR_DINC "SDL-2.0.x")
SET(SDL_VERSION_NAME "SDL2") SET(SDL_VERSION_NAME "SDL2")
SET(SDL_VERSION_SNAME "sdl") SET(SDL_VERSION_SNAME "sdl")
# ^ sdl > sdl2
ENDIF() ENDIF()
MARK_AS_ADVANCED(WANT_USE_SDL2)
OPTION(WANT_DEV_OUTPATH "Use developer friendly output paths." OFF)
IF(UNIX AND "${CMAKE_SYSTEM_NAME}" MATCHES "^[A-Z][a-z]*BSD$")
SET(MEGAGLEST_FRIENDLY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/mk/bsd/")
ELSEIF(UNIX AND NOT APPLE)
SET(MEGAGLEST_FRIENDLY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/mk/linux/")
ELSEIF(UNIX AND APPLE)
SET(MEGAGLEST_FRIENDLY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/mk/macosx/")
ELSE()
SET(MEGAGLEST_FRIENDLY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/data/glest_game/")
ENDIF()
IF(WIN32) IF(WIN32)
SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
@@ -505,3 +474,6 @@ endforeach()
MARK_AS_ADVANCED(${SDL_VERSION_NAME}MAIN_LIBRARY) MARK_AS_ADVANCED(${SDL_VERSION_NAME}MAIN_LIBRARY)
MARK_AS_ADVANCED(${SDL_VERSION_NAME}_INCLUDE_DIR) MARK_AS_ADVANCED(${SDL_VERSION_NAME}_INCLUDE_DIR)
MARK_AS_ADVANCED(${SDL_VERSION_NAME}_LIBRARY) MARK_AS_ADVANCED(${SDL_VERSION_NAME}_LIBRARY)
MARK_AS_ADVANCED(wxWidgets_CONFIG_EXECUTABLE)
MARK_AS_ADVANCED(wxWidgets_wxrc_EXECUTABLE)
MARK_AS_ADVANCED(wxWidgets_USE_DEBUG)

View File

@@ -0,0 +1,50 @@
#
# Curl Get Config
#
# IF we are using a system that supports curl-config use it.
#
IF(CURL_FOUND)
IF(UNIX AND NOT APPLE)
FIND_PROGRAM( CMAKE_CURL_CONFIG curl-config)
MARK_AS_ADVANCED(CMAKE_CURL_CONFIG)
IF(CMAKE_CURL_CONFIG)
IF(STATIC_CURL)
# run the curl-config program to get --static-libs
EXEC_PROGRAM(sh
ARGS "${CMAKE_CURL_CONFIG} --static-libs"
OUTPUT_VARIABLE CURL_STATIC_LIBS
RETURN_VALUE RET)
MESSAGE(STATUS "CURL RET = ${RET} libs: [${CURL_STATIC_LIBS}]")
ELSE()
SET(RET 1)
ENDIF()
IF(RET EQUAL 0 AND CURL_STATIC_LIBS)
MESSAGE(STATUS "#2 CURL RET = ${RET}, using CURL static libs")
SET(CURL_LIBRARIES "-Bstatic ${CURL_STATIC_LIBS}")
ELSE()
EXEC_PROGRAM(sh
ARGS "${CMAKE_CURL_CONFIG} --libs"
OUTPUT_VARIABLE CURL_DYNAMIC_LIBS
RETURN_VALUE RET2)
IF(RET2 EQUAL 0 AND CURL_DYNAMIC_LIBS)
MESSAGE(STATUS "#2 CURL RET = ${RET2}, using CURL dynamic libs: ${CURL_DYNAMIC_LIBS}")
SET(CURL_LIBRARIES "${CURL_DYNAMIC_LIBS}")
ELSE()
MESSAGE(STATUS "#3 CURL RET = ${RET2}, using CURL libs found by cmake: ${CURL_LIBRARIES}")
ENDIF()
ENDIF()
ENDIF()
ENDIF()
IF(CURL_VERSION_STRING AND "${CURL_VERSION_STRING}" VERSION_LESS "${CURL_MIN_VERSION_MG}")
MESSAGE(STATUS "(please visit http://curl.haxx.se/libcurl/ to find a newer version)")
MESSAGE(FATAL_ERROR " CURL version = [${CURL_VERSION_STRING}] we require AT LEAST [7.16.4]")
ENDIF()
ELSE()
SET(CURL_LIBRARIES)
SET(CURL_INCLUDE_DIRS)
ENDIF()

View File

@@ -1,71 +0,0 @@
# - Find curl
# Find the native CURL headers and libraries.
#
# CURL_INCLUDE_DIRS - where to find curl/curl.h, etc.
# CURL_LIBRARIES - List of libraries when using curl.
# CURL_FOUND - True if curl found.
# Look for the header file.
FIND_PATH(CURL_INCLUDE_DIR NAMES curl/curl.h
PATHS /usr/local/include/
/usr/include/
/opt/local/include/)
MARK_AS_ADVANCED(CURL_INCLUDE_DIR)
# Look for the library.
FIND_LIBRARY(CURL_LIBRARY NAMES curl curl-gnutls
PATHS /usr/local/lib/
/usr/lib/
/opt/local/lib/)
MARK_AS_ADVANCED(CURL_LIBRARY)
# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CURL DEFAULT_MSG CURL_LIBRARY CURL_INCLUDE_DIR)
IF(CURL_FOUND)
SET(CURL_LIBRARIES ${CURL_LIBRARY})
SET(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR})
# IF we are using a system that supports curl-config use it
# and force using static libs
IF(UNIX AND NOT APPLE)
FIND_PROGRAM( CMAKE_CURL_CONFIG curl-config)
MARK_AS_ADVANCED(CMAKE_CURL_CONFIG)
IF(CMAKE_CURL_CONFIG)
OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF)
OPTION(FORCE_CURL_DYNAMIC_LIBS "force the use of dynamic libs for CURL" OFF)
MESSAGE(STATUS "Force Curl dynamic: ${FORCE_CURL_DYNAMIC_LIBS}")
IF(WANT_STATIC_LIBS AND NOT FORCE_CURL_DYNAMIC_LIBS)
# run the curl-config program to get --static-libs
EXEC_PROGRAM(sh
ARGS "${CMAKE_CURL_CONFIG} --static-libs"
OUTPUT_VARIABLE CURL_STATIC_LIBS
RETURN_VALUE RET)
MESSAGE(STATUS "CURL RET = ${RET} libs: [${CURL_STATIC_LIBS}]")
ELSE()
SET(RET 1)
ENDIF()
IF(RET EQUAL 0 AND CURL_STATIC_LIBS)
MESSAGE(STATUS "#2 CURL RET = ${RET}, using CURL static libs")
SET(CURL_LIBRARIES "-Bstatic ${CURL_STATIC_LIBS}")
ELSE()
EXEC_PROGRAM(sh
ARGS "${CMAKE_CURL_CONFIG} --libs"
OUTPUT_VARIABLE CURL_STATIC_LIBS
RETURN_VALUE RET)
MESSAGE(STATUS "#2 CURL RET = ${RET}, using CURL dynamic libs: ${CURL_STATIC_LIBS}")
SET(CURL_LIBRARIES "${CURL_STATIC_LIBS}")
ENDIF()
ENDIF()
ENDIF()
ELSE(CURL_FOUND)
SET(CURL_LIBRARIES)
SET(CURL_INCLUDE_DIRS)
ENDIF(CURL_FOUND)

View File

@@ -10,11 +10,6 @@
# #
# #
OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF)
IF(WANT_STATIC_LIBS)
OPTION(FTGL_STATIC "Set to ON to link your project with static library (instead of DLL)." ON)
ENDIF()
#message(STATUS "!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #1 Searching for FTGL lib in custom path: [${FTGL_LIBRARY_PATH}]") #message(STATUS "!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #1 Searching for FTGL lib in custom path: [${FTGL_LIBRARY_PATH}]")
IF (FTGL_LIBRARY AND FTGL_INCLUDE_DIR) IF (FTGL_LIBRARY AND FTGL_INCLUDE_DIR)
@@ -30,9 +25,9 @@ ELSE (FTGL_LIBRARY AND FTGL_INCLUDE_DIR)
PATHS /usr/local/include PATHS /usr/local/include
/usr/include) /usr/include)
IF (FTGL_STATIC AND NOT FTGL_LIBRARY) IF (STATIC_FTGL AND NOT FTGL_LIBRARY)
FIND_LIBRARY(FTGL_LIBRARY FIND_LIBRARY(FTGL_LIBRARY
NAMES libftgl.a ftgl libftgl libftgl.dll NAMES libftgl.a ftgl.a ftgl libftgl libftgl.dll
PATHS /usr/local/lib PATHS /usr/local/lib
/usr/lib /usr/lib
${FTGL_LIBRARY_PATH}) ${FTGL_LIBRARY_PATH})

View File

@@ -5,17 +5,13 @@
# FONTCONFIG_LIBRARIES - List of libraries when using FONTCONFIG. # FONTCONFIG_LIBRARIES - List of libraries when using FONTCONFIG.
# FONTCONFIG_FOUND - True if FONTCONFIG found. # FONTCONFIG_FOUND - True if FONTCONFIG found.
IF(WANT_STATIC_LIBS)
OPTION(FONTCONFIG_STATIC "Set to ON to link your project with static library (instead of DLL)." ON)
ENDIF()
# Look for the header file. # Look for the header file.
FIND_PATH( FONTCONFIG_INCLUDE_DIR NAMES fontconfig/fontconfig.h FIND_PATH( FONTCONFIG_INCLUDE_DIR NAMES fontconfig/fontconfig.h
DOC "Path in which the file fontconfig/fontconfig.h is located." ) DOC "Path in which the file fontconfig/fontconfig.h is located." )
MARK_AS_ADVANCED(FONTCONFIG_INCLUDE_DIR) MARK_AS_ADVANCED(FONTCONFIG_INCLUDE_DIR)
IF(FONTCONFIG_STATIC) IF(STATIC_FONTCONFIG)
FIND_LIBRARY( FONTCONFIG_LIBRARY NAMES libfontconfig.a fontconfig FIND_LIBRARY( FONTCONFIG_LIBRARY NAMES libfontconfig.a fontconfig.a fontconfig
DOC "Path to fontconfig library." ) DOC "Path to fontconfig library." )
ELSE() ELSE()
FIND_LIBRARY( FONTCONFIG_LIBRARY NAMES fontconfig FIND_LIBRARY( FONTCONFIG_LIBRARY NAMES fontconfig

View File

@@ -28,9 +28,8 @@ set(FRIBIDI_INCLUDE_DIR ${xFRIBIDI_INCLUDE_DIR})
SET(FRIBIDI_NAMES ${FRIBIDI_NAMES} fribidi libfribidi) SET(FRIBIDI_NAMES ${FRIBIDI_NAMES} fribidi libfribidi)
OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF) IF(STATIC_FriBiDi)
IF(WANT_STATIC_LIBS) SET(FRIBIDI_NAMES libfribidi.a fribidi.a ${FRIBIDI_NAMES})
SET(FRIBIDI_NAMES fribidi.a libfribidi.a ${FRIBIDI_NAMES})
ENDIF() ENDIF()
#MESSAGE(STATUS "** Searching for library names: [${FRIBIDI_NAMES}] ...") #MESSAGE(STATUS "** Searching for library names: [${FRIBIDI_NAMES}] ...")

View File

@@ -1,54 +1,62 @@
#.rst:
# Try to find GLEW library and include path. # FindGLEW
# Once done this will define # --------
# #
# GLEW_FOUND # Find the OpenGL Extension Wrangler Library (GLEW)
# GLEW_INCLUDE_PATH
# GLEW_LIBRARY
# #
# IMPORTED Targets
# ^^^^^^^^^^^^^^^^
#
# This module defines the :prop_tgt:`IMPORTED` target ``GLEW::GLEW``,
# if GLEW has been found.
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# This module defines the following variables:
#
# ::
#
# GLEW_INCLUDE_DIRS - include directories for GLEW
# GLEW_LIBRARIES - libraries to link against GLEW
# GLEW_FOUND - true if GLEW has been found and can be used
IF (WIN32) #=============================================================================
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h # Copyright 2012 Benjamin Eikel
$ENV{PROGRAMFILES}/GLEW/include # Copyright 2015 filux <heross(@@)o2.pl>
${PROJECT_SOURCE_DIR}/src/nvgl/glew/include #
DOC "The directory where GL/glew.h resides") # Distributed under the OSI-approved BSD License (the "License");
FIND_LIBRARY( GLEW_LIBRARY # see accompanying file Copyright.txt for details.
NAMES glew GLEW glew32 glew32s #
PATHS # This software is distributed WITHOUT ANY WARRANTY; without even the
$ENV{PROGRAMFILES}/GLEW/lib # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin # See the License for more information.
${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib #=============================================================================
DOC "The GLEW library") # (To distribute this file outside of CMake, substitute the full
ELSE (WIN32) # License text for the above reference.)
SET(GLEW_NAMES ${GLEW_NAMES} GLEW glew) find_path(GLEW_INCLUDE_DIR GL/glew.h)
OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF)
IF(WANT_STATIC_LIBS)
SET(GLEW_NAMES libGLEW.a libglew.a ${GLEW_NAMES})
ENDIF()
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h SET(GLEW_NAMES ${GLEW_NAMES} GLEW glew32 glew glew32s)
/usr/include IF(STATIC_GLEW)
/usr/local/include SET(GLEW_NAMES libGLEW.a libglew32.a libglew.a libglew32s.a GLEW.a glew32.a glew.a glew32s.a ${GLEW_NAMES})
/sw/include
/opt/local/include
DOC "The directory where GL/glew.h resides")
FIND_LIBRARY( GLEW_LIBRARY
NAMES ${GLEW_NAMES}
PATHS
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
/sw/lib
/opt/local/lib
DOC "The GLEW library")
ENDIF (WIN32)
IF(GLEW_INCLUDE_PATH)
SET( GLEW_FOUND 1 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
ELSE()
SET( GLEW_FOUND 0 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
ENDIF() ENDIF()
MARK_AS_ADVANCED(GLEW_FOUND GLEW_INCLUDE_PATH GLEW_LIBRARY) find_library(GLEW_LIBRARY NAMES ${GLEW_NAMES} PATH_SUFFIXES lib64)
set(GLEW_INCLUDE_DIRS ${GLEW_INCLUDE_DIR})
set(GLEW_LIBRARIES ${GLEW_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GLEW REQUIRED_VARS GLEW_INCLUDE_DIR GLEW_LIBRARY)
if(GLEW_FOUND AND NOT TARGET GLEW::GLEW)
add_library(GLEW::GLEW UNKNOWN IMPORTED)
set_target_properties(GLEW::GLEW PROPERTIES
IMPORTED_LOCATION "${GLEW_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
message(STATUS "GLEW_LIBRARY: ${GLEW_LIBRARIES}")
endif()
mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY)

View File

@@ -132,4 +132,4 @@ IF(BREAKPAD_FOUND)
#SET(BREAKPAD_FOUND FALSE) #SET(BREAKPAD_FOUND FALSE)
ENDIF(BREAKPAD_DUMPSYMS_EXE) ENDIF(BREAKPAD_DUMPSYMS_EXE)
ENDIF(BREAKPAD_FOUND) ENDIF(BREAKPAD_FOUND)
MARK_AS_ADVANCED(BREAKPAD_INCLUDE_DIR)

View File

@@ -41,12 +41,8 @@ FIND_PATH(IRCCLIENT_INCLUDE_DIR libircclient.h
SET(IRCCLIENT_FIND_LIBRARIES ircclient) SET(IRCCLIENT_FIND_LIBRARIES ircclient)
OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF) IF(STATIC_Ircclient)
OPTION(FORCE_IRCCLIENT_DYNAMIC_LIBS "force the use of dynamic libs for IRCCLIENT" OFF) SET(IRCCLIENT_FIND_LIBRARIES libircclient.a ircclient.a libircclient ircclient)
MESSAGE(STATUS "Force IRCCLient dynamic: ${FORCE_IRCCLIENT_DYNAMIC_LIBS}")
IF(WANT_STATIC_LIBS AND NOT FORCE_IRCCLIENT_DYNAMIC_LIBS)
SET(IRCCLIENT_FIND_LIBRARIES libircclient.a ircclient.a)
ELSE() ELSE()
SET(IRCCLIENT_FIND_LIBRARIES libircclient ircclient) SET(IRCCLIENT_FIND_LIBRARIES libircclient ircclient)
ENDIF() ENDIF()

View File

@@ -46,7 +46,6 @@ find_path(LIBVLC_INCLUDE_DIR PATHS "${CMAKE_INCLUDE_PATH}/vlc" NAMES vlc.h
HINTS ${PC_LIBVLC_INCLUDEDIR} ${PC_LIBVLC_INCLUDE_DIRS}) HINTS ${PC_LIBVLC_INCLUDEDIR} ${PC_LIBVLC_INCLUDE_DIRS})
# dream on libvlc doesn't support static linking # dream on libvlc doesn't support static linking
#OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF)
set(LIBVLC_LIB_NAMES vlc libvlc) set(LIBVLC_LIB_NAMES vlc libvlc)
set(LIBVLC_LIB_CORE_NAMES vlccore libvlccore) set(LIBVLC_LIB_CORE_NAMES vlccore libvlccore)
#IF(WANT_STATIC_LIBS) #IF(WANT_STATIC_LIBS)

View File

@@ -1,104 +1,195 @@
# Find the Lua 5.1 includes and library #.rst:
# FindLua
# -------
# #
# LUA_INCLUDE_DIR - where to find lua.h
# LUA_LIBRARIES - List of fully qualified libraries to link against
# LUA_FOUND - Set to TRUE if found
# Copyright (c) 2007, Pau Garcia i Quiles, <pgquiles@elpauer.org>
# #
# Redistribution and use is allowed according to the terms of the BSD license. #
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. # Locate Lua library This module defines
#
# ::
#
# LUA_FOUND - if false, do not try to link to Lua
# LUA_LIBRARIES - both lua and lualib
# LUA_INCLUDE_DIR - where to find lua.h
# LUA_VERSION_STRING - the version of Lua found
# LUA_VERSION_MAJOR - the major version of Lua
# LUA_VERSION_MINOR - the minor version of Lua
# LUA_VERSION_PATCH - the patch version of Lua
#
#
#
# Note that the expected include convention is
#
# ::
#
# #include "lua.h"
#
# and not
#
# ::
#
# #include <lua/lua.h>
#
# This is because, the lua location is not standardized and may exist in
# locations other than lua/
OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF) #=============================================================================
IF(WANT_STATIC_LIBS) # Copyright 2007-2009 Kitware, Inc.
OPTION(LUA_STATIC "Set to ON to link your project with static library (instead of DLL)." ON) # Copyright 2013 Rolf Eike Beer <eike@sf-mail.de>
ENDIF() # Copyright 2015 filux <heross(@@)o2.pl>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
IF(LUA_INCLUDE_DIR AND LUA_LIBRARIES) unset(_lua_include_subdirs)
#SET(LUA_FIND_QUIETLY TRUE) unset(_lua_library_names)
ENDIF(LUA_INCLUDE_DIR AND LUA_LIBRARIES)
IF(FORCE_LUA_5_3) IF("${FORCE_LUA_VERSION}" STREQUAL "OFF")
MESSAGE(STATUS "Trying to FORCE LUA 5.3 ...") IF(DEFINED ALL_LUA_VERSIONS_IN_ORDER)
SET(LUA_VERSIONS5 "${ALL_LUA_VERSIONS_IN_ORDER}")
SET(LUA_FIND_INCLUDE_PATHS /usr/include/lua5.3 ELSE()
/usr/include/lua SET(LUA_VERSIONS5 5.3 5.2 5.1 5.0)
/usr/include ) ENDIF()
SET(LUA_FIND_STATIC_LIB_NAMES liblua5.3.a lua5.3 liblua.a lua )
SET(LUA_FIND_DYNAMIC_LIB_NAMES lua5.3 lua )
ELSEIF(FORCE_LUA_5_2)
MESSAGE(STATUS "Trying to FORCE LUA 5.2 ...")
SET(LUA_FIND_INCLUDE_PATHS /usr/include/lua5.2
/usr/include/lua
/usr/include )
SET(LUA_FIND_STATIC_LIB_NAMES liblua5.2.a lua5.2 liblua.a lua )
SET(LUA_FIND_DYNAMIC_LIB_NAMES lua5.2 lua )
ELSEIF(FORCE_LUA_5_1)
MESSAGE(STATUS "Trying to FORCE LUA 5.1 ...")
SET(LUA_FIND_INCLUDE_PATHS /usr/include/lua5.1
/usr/include/lua
/usr/include )
SET(LUA_FIND_STATIC_LIB_NAMES liblua5.1.a lua5.1 liblua.a lua )
SET(LUA_FIND_DYNAMIC_LIB_NAMES lua5.1 lua )
ELSE() ELSE()
SET(LUA_FIND_INCLUDE_PATHS /usr/include/lua5.3 SET(LUA_VERSIONS5 "${FORCE_LUA_VERSION}")
/usr/include/lua5.2
/usr/include/lua
/usr/include/lua5.1
/usr/include )
SET(LUA_FIND_STATIC_LIB_NAMES liblua5.3.a liblua5.2.a liblua.a liblua5.1.a lua5.3 lua5.2 lua lua5.1 )
SET(LUA_FIND_DYNAMIC_LIB_NAMES lua5.3 lua5.2 lua lua5.1 )
ENDIF() ENDIF()
FIND_PATH(LUA_INCLUDE_DIR NAMES lua.hpp # this is a function only to have all the variables inside go away automatically
PATHS ${LUA_FIND_INCLUDE_PATHS} function(set_lua_version_vars)
IF(FreeBSD) if (Lua_FIND_VERSION_EXACT)
SET(PATHS "/usr/local/include/lua53 /usr/local/include/lua52 /usr/local/include/lua51") if (Lua_FIND_VERSION_COUNT GREATER 1)
ENDIF() set(lua_append_versions ${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR})
$ENV{LUA_HOME}) endif ()
elseif (Lua_FIND_VERSION)
# once there is a different major version supported this should become a loop
if (NOT Lua_FIND_VERSION_MAJOR GREATER 5)
if (Lua_FIND_VERSION_COUNT EQUAL 1)
set(lua_append_versions ${LUA_VERSIONS5})
else ()
foreach (subver IN LISTS LUA_VERSIONS5)
if (NOT subver VERSION_LESS ${Lua_FIND_VERSION})
list(APPEND lua_append_versions ${subver})
endif ()
endforeach ()
endif ()
endif ()
else ()
# once there is a different major version supported this should become a loop
set(lua_append_versions ${LUA_VERSIONS5})
endif ()
IF (LUA_STATIC AND NOT LUA_LIBRARIES) foreach (ver IN LISTS lua_append_versions)
FIND_LIBRARY(LUA_LIBRARIES NAMES ${LUA_FIND_STATIC_LIB_NAMES} string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _ver "${ver}")
PATHS list(APPEND _lua_include_subdirs
IF(FreeBSD) include/lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
SET(PATHS "/usr/local/lib/lua53 /usr/local/lib/lua52 /usr/local/lib/lua51") include/lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
ENDIF() include/lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
$ENV{LUA_HOME}) )
IF(STATIC_LUA)
list(APPEND _lua_library_names
liblua${CMAKE_MATCH_1}${CMAKE_MATCH_2}.a
liblua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.a
liblua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.a
lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}.a
lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.a
lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.a
)
ENDIF()
list(APPEND _lua_library_names
lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
)
endforeach ()
ELSE() set(_lua_include_subdirs "${_lua_include_subdirs}" PARENT_SCOPE)
FIND_LIBRARY(LUA_LIBRARIES NAMES ${LUA_FIND_DYNAMIC_LIB_NAMES} set(_lua_library_names "${_lua_library_names}" PARENT_SCOPE)
PATHS endfunction(set_lua_version_vars)
IF(FreeBSD)
SET(PATHS "/usr/local/lib/lua53 /usr/local/lib/lua52 /usr/local/lib/lua51") set_lua_version_vars()
ENDIF()
$ENV{LUA_HOME}) find_path(LUA_INCLUDE_DIR lua.h
HINTS
ENV LUA_DIR
PATH_SUFFIXES ${_lua_include_subdirs} include/lua include
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
unset(_lua_include_subdirs)
IF(STATIC_LUA AND APPLE)
# at least in mac ports, static lib is without numbers in name
SET(_lua_library_names lua.a liblua.a ${_lua_library_names})
ENDIF() ENDIF()
#MESSAGE(STATUS "LUA_INC: ${LUA_INCLUDE_DIR}") find_library(LUA_LIBRARY
#MESSAGE(STATUS "LUA_LIB: ${LUA_LIBRARIES}") NAMES ${_lua_library_names} lua
HINTS
ENV LUA_DIR
PATH_SUFFIXES lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
)
unset(_lua_library_names)
IF(LUA_INCLUDE_DIR AND LUA_LIBRARIES) if (LUA_LIBRARY)
SET(LUA_FOUND TRUE) # include the math library for Unix
INCLUDE(CheckLibraryExists) if (UNIX AND NOT APPLE AND NOT BEOS)
CHECK_LIBRARY_EXISTS(${LUA_LIBRARIES} lua_close "" LUA_NEED_PREFIX) find_library(LUA_MATH_LIBRARY m)
ELSE(LUA_INCLUDE_DIR AND LUA_LIBRARIES) set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}")
SET(LUA_FOUND FALSE) # For Windows and Mac, don't need to explicitly include the math library
ENDIF (LUA_INCLUDE_DIR AND LUA_LIBRARIES) else ()
set(LUA_LIBRARIES "${LUA_LIBRARY}")
endif ()
endif ()
IF(LUA_FOUND) if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
IF (NOT LUA_FIND_QUIETLY) # At least 5.[012] have different ways to express the version
MESSAGE(STATUS "Found Lua library: ${LUA_LIBRARIES}") # so all of them need to be tested. Lua 5.2 defines LUA_VERSION
MESSAGE(STATUS "Found Lua headers: ${LUA_INCLUDE_DIR}") # and LUA_RELEASE as joined by the C preprocessor, so avoid those.
ENDIF (NOT LUA_FIND_QUIETLY) file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_strings
ELSE(LUA_FOUND) REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*")
IF(LUA_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could NOT find Lua")
ENDIF(LUA_FIND_REQUIRED)
ENDIF(LUA_FOUND)
MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES) string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};")
if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$")
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};")
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};")
set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
else ()
string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$")
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
endif ()
string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}")
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}")
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}")
endif ()
unset(lua_version_strings)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)

View File

@@ -1,36 +0,0 @@
# Find the LuaJIT includes and library
#
# LUAJIT_INCLUDE_DIR - where to find lua.h
# LUAJIT_LIBRARIES - List of fully qualified libraries to link against
# LUAJIT_FOUND - Set to TRUE if found
# Copyright (c) 2012, Mark Vejvoda, <mark_vejvoda@hotmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF)
IF(WANT_STATIC_LIBS)
OPTION(LUAJIT_FIND_STATIC "Set to ON to link your project with static library (instead of DLL)." ON)
ENDIF()
find_path(LUAJIT_INCLUDE_DIR luajit.h
NAMES luajit.h
PATH_SUFFIXES luajit-2.0)
if (LUAJIT_FIND_STATIC)
find_library(LUAJIT_LIBRARIES luajit.a
NAMES libluajit-5.1.a)
else (LUATJIT_FIND_STATIC)
find_library(LUAJIT_LIBRARIES luajit
NAMES luajit-5.1)
endif (LUAJIT_FIND_STATIC)
mark_as_advanced(LUAJIT_INCLUDE_DIR)
mark_as_advanced(LUAJIT_LIBRARIES)
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LUAJIT DEFAULT_MSG LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR)

View File

@@ -41,31 +41,30 @@ SET(MINIUPNPC_DIR_SEARCH $ENV{MINIUPNPC_ROOT})
# PATH_SUFFIXES miniupnpc) # PATH_SUFFIXES miniupnpc)
FIND_PATH(MINIUPNP_INCLUDE_DIR miniupnpc.h FIND_PATH(MINIUPNP_INCLUDE_DIR miniupnpc.h
${MINIUPNPC_DIR_SEARCH}/include/miniupnpc PATHS ${MINIUPNPC_DIR_SEARCH}/include
/usr/include/miniupnpc /usr/include
/usr/local/include/miniupnpc) /usr/local/include
PATH_SUFFIXES miniupnpc)
#message(STATUS "Finding miniupnpc.h result: ${MINIUPNP_INCLUDE_DIR}") #message(STATUS "Finding miniupnpc.h result: ${MINIUPNP_INCLUDE_DIR}")
#find_library(MINIUPNP_LIBRARY miniupnpc) #find_library(MINIUPNP_LIBRARY miniupnpc)
set(MINIUPNPC_LIBRARY_NAMES ${MINIUPNPC_LIBRARY_DYNAMIC_NAME} libminiupnpc miniupnpc)
IF(WANT_STATIC_LIBS) IF(STATIC_Miniupnpc)
set(MINIUPNPC_LIBRARY_NAMES ${MINIUPNPC_LIBRARY_STATIC_NAME} libminiupnpc.a) set(MINIUPNPC_LIBRARY_NAMES ${MINIUPNPC_LIBRARY_STATIC_NAME} libminiupnpc.a miniupnpc.a ${MINIUPNPC_LIBRARY_NAMES})
ELSE()
set(MINIUPNPC_LIBRARY_NAMES ${MINIUPNPC_LIBRARY_DYNAMIC_NAME} libminiupnpc.so miniupnpc)
ENDIF() ENDIF()
FIND_LIBRARY(MINIUPNP_LIBRARY NAMES ${MINIUPNPC_LIBRARY_NAMES}) FIND_LIBRARY(MINIUPNP_LIBRARY NAMES ${MINIUPNPC_LIBRARY_NAMES})
#message(STATUS "Finding miniupnpc lib result: ${MINIUPNP_LIBRARY}") #message(STATUS "Finding miniupnpc lib result: ${MINIUPNP_LIBRARY}")
if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY) include(FindPackageHandleStandardArgs)
set (MINIUPNP_FOUND TRUE) FIND_PACKAGE_HANDLE_STANDARD_ARGS(MINIUPNP REQUIRED_VARS MINIUPNP_LIBRARY MINIUPNP_INCLUDE_DIR)
endif ()
if (MINIUPNP_FOUND) if (MINIUPNP_FOUND)
if (NOT MINIUPNP_FIND_QUIETLY) if (NOT MINIUPNP_FIND_QUIETLY)
message (STATUS "Found the miniupnpc libraries at ${MINIUPNP_LIBRARY}") #message (STATUS "Found the miniupnpc libraries at ${MINIUPNP_LIBRARY}")
message (STATUS "Found the miniupnpc headers at ${MINIUPNP_INCLUDE_DIR}") message (STATUS "Found the miniupnpc headers at ${MINIUPNP_INCLUDE_DIR}")
endif (NOT MINIUPNP_FIND_QUIETLY) endif (NOT MINIUPNP_FIND_QUIETLY)

View File

@@ -6,11 +6,6 @@
# VORBIS_FILE_LIBRARY # VORBIS_FILE_LIBRARY
# #
OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF)
IF(WANT_STATIC_LIBS)
OPTION(OGG_STATIC "Set to ON to link your project with static library (instead of DLL)." ON)
ENDIF()
# check for cache to avoid littering log # check for cache to avoid littering log
IF(OGG_INCLUDE_DIR AND OGG_LIBRARY AND VORBIS_LIBRARY) IF(OGG_INCLUDE_DIR AND OGG_LIBRARY AND VORBIS_LIBRARY)
SET(OGG_BE_QUIET TRUE) SET(OGG_BE_QUIET TRUE)
@@ -18,14 +13,14 @@ ENDIF()
FIND_PATH(OGG_INCLUDE_DIR ogg/ogg.h) FIND_PATH(OGG_INCLUDE_DIR ogg/ogg.h)
IF (OGG_STATIC AND NOT OGG_LIBRARY) IF (STATIC_OGG AND NOT OGG_LIBRARY)
FIND_LIBRARY(OGG_LIBRARY NAMES libogg.a ogg) FIND_LIBRARY(OGG_LIBRARY NAMES libogg.a ogg.a ogg)
ELSE() ELSE()
FIND_LIBRARY(OGG_LIBRARY NAMES ogg) FIND_LIBRARY(OGG_LIBRARY NAMES ogg)
ENDIF() ENDIF()
IF (OGG_STATIC AND NOT VORBIS_LIBRARY) IF (STATIC_OGG AND NOT VORBIS_LIBRARY)
FIND_LIBRARY(VORBIS_LIBRARY NAMES libvorbis.a vorbis) FIND_LIBRARY(VORBIS_LIBRARY NAMES libvorbis.a vorbis.a vorbis)
ELSE() ELSE()
FIND_LIBRARY(VORBIS_LIBRARY NAMES vorbis) FIND_LIBRARY(VORBIS_LIBRARY NAMES vorbis)
ENDIF() ENDIF()
@@ -34,8 +29,8 @@ ENDIF()
#IF(NOT APPLE) #IF(NOT APPLE)
# comment above is full of lies # comment above is full of lies
IF (OGG_STATIC AND NOT VORBIS_FILE_LIBRARY) IF (STATIC_OGG AND NOT VORBIS_FILE_LIBRARY)
FIND_LIBRARY(VORBIS_FILE_LIBRARY NAMES libvorbisfile.a vorbisfile) FIND_LIBRARY(VORBIS_FILE_LIBRARY NAMES libvorbisfile.a vorbisfile.a vorbisfile)
ELSE() ELSE()
FIND_LIBRARY(VORBIS_FILE_LIBRARY NAMES vorbisfile) FIND_LIBRARY(VORBIS_FILE_LIBRARY NAMES vorbisfile)
ENDIF() ENDIF()

View File

@@ -1,263 +0,0 @@
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> ... )
#
# This function is intended to be used in FindXXX.cmake modules files.
# It handles the REQUIRED, QUIET and version-related arguments to FIND_PACKAGE().
# It also sets the <UPPERCASED_NAME>_FOUND variable.
# The package is considered found if all variables <var1>... listed contain
# valid results, e.g. valid filepaths.
#
# There are two modes of this function. The first argument in both modes is
# the name of the Find-module where it is called (in original casing).
#
# The first simple mode looks like this:
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> (DEFAULT_MSG|"Custom failure message") <var1>...<varN> )
# If the variables <var1> to <varN> are all valid, then <UPPERCASED_NAME>_FOUND
# will be set to TRUE.
# If DEFAULT_MSG is given as second argument, then the function will generate
# itself useful success and error messages. You can also supply a custom error message
# for the failure case. This is not recommended.
#
# The second mode is more powerful and also supports version checking:
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS <var1>...<varN>]
# [VERSION_VAR <versionvar>
# [CONFIG_MODE]
# [FAIL_MESSAGE "Custom failure message"] )
#
# As above, if <var1> through <varN> are all valid, <UPPERCASED_NAME>_FOUND
# will be set to TRUE.
# After REQUIRED_VARS the variables which are required for this package are listed.
# Following VERSION_VAR the name of the variable can be specified which holds
# the version of the package which has been found. If this is done, this version
# will be checked against the (potentially) specified required version used
# in the find_package() call. The EXACT keyword is also handled. The default
# messages include information about the required version and the version
# which has been actually found, both if the version is ok or not.
# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for
# a find_package(... NO_MODULE) call, in this case all the information
# provided by the config-mode of find_package() will be evaluated
# automatically.
# Via FAIL_MESSAGE a custom failure message can be specified, if this is not
# used, the default message will be displayed.
#
# Example for mode 1:
#
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
#
# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and
# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE.
# If it is not found and REQUIRED was used, it fails with FATAL_ERROR,
# independent whether QUIET was used or not.
# If it is found, success will be reported, including the content of <var1>.
# On repeated Cmake runs, the same message won't be printed again.
#
# Example for mode 2:
#
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE
# VERSION_VAR BISON_VERSION)
# In this case, BISON is considered to be found if the variable(s) listed
# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case.
# Also the version of BISON will be checked by using the version contained
# in BISON_VERSION.
# Since no FAIL_MESSAGE is given, the default messages will be printed.
#
# Another example for mode 2:
#
# FIND_PACKAGE(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4 CONFIG_MODE)
# In this case, FindAutmoc4.cmake wraps a call to FIND_PACKAGE(Automoc4 NO_MODULE)
# and adds an additional search directory for automoc4.
# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper
# success/error message.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
INCLUDE(FindPackageMessage)
IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
INCLUDE(CMakeParseArguments)
ENDIF()
# internal helper macro
MACRO(_FPHSA_FAILURE_MESSAGE _msg)
IF (${_NAME}_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "${_msg}")
ELSE (${_NAME}_FIND_REQUIRED)
IF (NOT ${_NAME}_FIND_QUIETLY)
MESSAGE(STATUS "${_msg}")
ENDIF (NOT ${_NAME}_FIND_QUIETLY)
ENDIF (${_NAME}_FIND_REQUIRED)
ENDMACRO(_FPHSA_FAILURE_MESSAGE _msg)
# internal helper macro to generate the failure message when used in CONFIG_MODE:
MACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
# <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
IF(${_NAME}_CONFIG)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
ELSE(${_NAME}_CONFIG)
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
# List them all in the error message:
IF(${_NAME}_CONSIDERED_CONFIGS)
SET(configsText "")
LIST(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
MATH(EXPR configsCount "${configsCount} - 1")
FOREACH(currentConfigIndex RANGE ${configsCount})
LIST(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
LIST(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
SET(configsText "${configsText} ${filename} (version ${version})\n")
ENDFOREACH(currentConfigIndex)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
ELSE(${_NAME}_CONSIDERED_CONFIGS)
# Simple case: No Config-file was found at all:
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
ENDIF(${_NAME}_CONSIDERED_CONFIGS)
ENDIF(${_NAME}_CONFIG)
ENDMACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
# new extended or in the "old" mode:
SET(options CONFIG_MODE)
SET(oneValueArgs FAIL_MESSAGE VERSION_VAR)
SET(multiValueArgs REQUIRED_VARS)
SET(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
LIST(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
IF(${INDEX} EQUAL -1)
SET(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
SET(FPHSA_REQUIRED_VARS ${ARGN})
SET(FPHSA_VERSION_VAR)
ELSE(${INDEX} EQUAL -1)
CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
IF(FPHSA_UNPARSED_ARGUMENTS)
MESSAGE(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
ENDIF(FPHSA_UNPARSED_ARGUMENTS)
IF(NOT FPHSA_FAIL_MESSAGE)
SET(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
ENDIF(NOT FPHSA_FAIL_MESSAGE)
ENDIF(${INDEX} EQUAL -1)
# now that we collected all arguments, process them
IF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG")
SET(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
ENDIF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG")
# In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
# when it successfully found the config-file, including version checking:
IF(FPHSA_CONFIG_MODE)
LIST(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
LIST(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
SET(FPHSA_VERSION_VAR ${_NAME}_VERSION)
ENDIF(FPHSA_CONFIG_MODE)
IF(NOT FPHSA_REQUIRED_VARS)
MESSAGE(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
ENDIF(NOT FPHSA_REQUIRED_VARS)
LIST(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
STRING(TOUPPER ${_NAME} _NAME_UPPER)
STRING(TOLOWER ${_NAME} _NAME_LOWER)
# collect all variables which were not found, so they can be printed, so the
# user knows better what went wrong (#6375)
SET(MISSING_VARS "")
SET(DETAILS "")
SET(${_NAME_UPPER}_FOUND TRUE)
# check if all passed variables are valid
FOREACH(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
IF(NOT ${_CURRENT_VAR})
SET(${_NAME_UPPER}_FOUND FALSE)
SET(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}")
ELSE(NOT ${_CURRENT_VAR})
SET(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]")
ENDIF(NOT ${_CURRENT_VAR})
ENDFOREACH(_CURRENT_VAR)
# version handling:
SET(VERSION_MSG "")
SET(VERSION_OK TRUE)
SET(VERSION ${${FPHSA_VERSION_VAR}} )
IF (${_NAME}_FIND_VERSION)
IF(VERSION)
IF(${_NAME}_FIND_VERSION_EXACT) # exact version required
IF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
SET(VERSION_OK FALSE)
ELSE (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
SET(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
ENDIF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
ELSE(${_NAME}_FIND_VERSION_EXACT) # minimum version specified:
IF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
SET(VERSION_OK FALSE)
ELSE ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
SET(VERSION_MSG "(found suitable version \"${VERSION}\", required is \"${${_NAME}_FIND_VERSION}\")")
ENDIF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
ENDIF(${_NAME}_FIND_VERSION_EXACT)
ELSE(VERSION)
# if the package was not found, but a version was given, add that to the output:
IF(${_NAME}_FIND_VERSION_EXACT)
SET(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
ELSE(${_NAME}_FIND_VERSION_EXACT)
SET(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
ENDIF(${_NAME}_FIND_VERSION_EXACT)
ENDIF(VERSION)
ELSE (${_NAME}_FIND_VERSION)
IF(VERSION)
SET(VERSION_MSG "(found version \"${VERSION}\")")
ENDIF(VERSION)
ENDIF (${_NAME}_FIND_VERSION)
IF(VERSION_OK)
SET(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]")
ELSE(VERSION_OK)
SET(${_NAME_UPPER}_FOUND FALSE)
ENDIF(VERSION_OK)
# print the result:
IF (${_NAME_UPPER}_FOUND)
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG}" "${DETAILS}")
ELSE (${_NAME_UPPER}_FOUND)
IF(FPHSA_CONFIG_MODE)
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
ELSE(FPHSA_CONFIG_MODE)
IF(NOT VERSION_OK)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
ELSE(NOT VERSION_OK)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}")
ENDIF(NOT VERSION_OK)
ENDIF(FPHSA_CONFIG_MODE)
ENDIF (${_NAME_UPPER}_FOUND)
SET(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE)
ENDFUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _FIRST_ARG)

View File

@@ -46,17 +46,12 @@ IF (XERCESC_INCLUDE AND XERCESC_LIBRARY)
#MESSAGE(STATUS "Found cached Xerces-C lib [${XERCESC_LIBRARY}]") #MESSAGE(STATUS "Found cached Xerces-C lib [${XERCESC_LIBRARY}]")
ENDIF (XERCESC_INCLUDE AND XERCESC_LIBRARY) ENDIF (XERCESC_INCLUDE AND XERCESC_LIBRARY)
OPTION(WANT_STATIC_LIBS "builds as many static libs as possible" OFF) IF (NOT ${XERCESC_WAS_STATIC} STREQUAL ${STATIC_XercesC})
IF(WANT_STATIC_LIBS)
OPTION(XERCESC_STATIC "Set to ON to link your project with static library (instead of DLL)." ON)
ENDIF()
IF (NOT ${XERCESC_WAS_STATIC} STREQUAL ${XERCESC_STATIC})
UNSET(XERCESC_LIBRARY CACHE) UNSET(XERCESC_LIBRARY CACHE)
UNSET(XERCESC_LIBRARY_DEBUG CACHE) UNSET(XERCESC_LIBRARY_DEBUG CACHE)
ENDIF (NOT ${XERCESC_WAS_STATIC} STREQUAL ${XERCESC_STATIC}) ENDIF (NOT ${XERCESC_WAS_STATIC} STREQUAL ${STATIC_XercesC})
SET(XERCESC_WAS_STATIC ${XERCESC_STATIC} CACHE INTERNAL "" ) SET(XERCESC_WAS_STATIC ${STATIC_XercesC} CACHE INTERNAL "" )
IF (XERCESC_INCLUDE_DIR) IF (XERCESC_INCLUDE_DIR)
SET(XERCESC_INCLUDE ${XERCESC_INCLUDE_DIR}) SET(XERCESC_INCLUDE ${XERCESC_INCLUDE_DIR})
@@ -74,7 +69,7 @@ ENDIF()
#MESSAGE(STATUS "Current Xerces-C lib [${XERCESC_LIBRARY}] XERCESC_INCLUDE [${XERCESC_INCLUDE}") #MESSAGE(STATUS "Current Xerces-C lib [${XERCESC_LIBRARY}] XERCESC_INCLUDE [${XERCESC_INCLUDE}")
IF (XERCESC_STATIC AND NOT XERCESC_LIBRARY) IF (STATIC_XercesC AND NOT XERCESC_LIBRARY)
MESSAGE(STATUS "Looking for static Xerces-C lib...") MESSAGE(STATUS "Looking for static Xerces-C lib...")
FIND_LIBRARY(XERCESC_LIBRARY NAMES xerces-c_static_3 libxerces-c.a libxerces-c_3.a libxerces-c2_8_0.a libxerces-c_2.a libXerces.a FIND_LIBRARY(XERCESC_LIBRARY NAMES xerces-c_static_3 libxerces-c.a libxerces-c_3.a libxerces-c2_8_0.a libxerces-c_2.a libXerces.a
PATHS PATHS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
#
# Required Versions And Static Config
#
# Things related with "Static build" and optional versioning.
#
# By assumption in general all should be done in the way that the default dynamic
# compilation should work even without this file.
#
IF(WANT_STATIC_LIBS)
IF(BUILD_MEGAGLEST_MODEL_VIEWER OR BUILD_MEGAGLEST_MAP_EDITOR OR BUILD_MEGAGLEST)
# shared lib
FOREACH(STATIC_LIB
OpenSSL
CURL
XercesC
LUA
JPEG
PNG
FontConfig
FTGL
GLEW
FriBiDi
Miniupnpc
Ircclient)
LIST(APPEND LIST_OF_STATIC_LIBS_MG "${STATIC_LIB}")
ENDFOREACH()
ENDIF()
IF(BUILD_MEGAGLEST)
# only libs not used by shared lib
FOREACH(STATIC_LIB
OGG)
LIST(APPEND LIST_OF_STATIC_LIBS_MG "${STATIC_LIB}")
ENDFOREACH()
ENDIF()
FOREACH(STATIC_LIB ${LIST_OF_STATIC_LIBS_MG})
IF(DEFINED WANT_USE_${STATIC_LIB} AND NOT WANT_USE_${STATIC_LIB})
IF(DEFINED STATIC_${STATIC_LIB})
UNSET(STATIC_${STATIC_LIB} CACHE)
ENDIF()
ELSE()
OPTION("STATIC_${STATIC_LIB}" "Set to ON to link your project with static library (instead of DLL)." ON)
ENDIF()
ENDFOREACH()
ENDIF()
IF(STATIC_OpenSSL)
SET(OPENSSL_USE_STATIC_LIBS ON)
ENDIF()
IF(STATIC_CURL AND UNIX)
ADD_DEFINITIONS("-DCURL_STATICLIB")
ENDIF()
SET(CURL_MIN_VERSION_MG "7.16.4")
IF(NOT DEFINED FORCE_LUA_VERSION)
SET(FORCE_LUA_VERSION "OFF" CACHE STRING "Try to force some specific lua version (for example older). On the list may be also not existing versions yet for future use." FORCE)
ENDIF()
SET_PROPERTY(CACHE FORCE_LUA_VERSION PROPERTY STRINGS OFF 5.5 5.4 5.3 5.2 5.1 5.0)
SET(ALL_LUA_VERSIONS_IN_ORDER 5.3 5.2 5.1 5.4 5.5 5.0)
IF(STATIC_JPEG)
SET(JPEG_NAMES jpeg.a libjpeg.a ${JPEG_NAMES})
ENDIF()
IF(STATIC_PNG)
list(APPEND PNG_NAMES png.a libpng.a)
set(_PNG_VERSION_SUFFIXES 17 16 15 14 12 18 19 20 21 22)
foreach(v IN LISTS _PNG_VERSION_SUFFIXES)
list(APPEND PNG_NAMES png${v}.a libpng${v}.a)
list(APPEND PNG_NAMES_DEBUG png${v}d.a libpng${v}d.a)
endforeach()
unset(_PNG_VERSION_SUFFIXES)
ENDIF()
SET(VLC_MIN_VERSION_MG "1.1.0")

View File

@@ -19,9 +19,10 @@ CMAKE_ONLY=0
MAKE_ONLY=0 MAKE_ONLY=0
CLANG_FORCED=0 CLANG_FORCED=0
WANT_STATIC_LIBS="-DWANT_STATIC_LIBS=ON" WANT_STATIC_LIBS="-DWANT_STATIC_LIBS=ON"
FORCE_EMBEDDED_LIBS="-DFORCE_EMBEDDED_LIBS=OFF" FORCE_EMBEDDED_LIBS=0
LUA_FORCED_VERSION=0 LUA_FORCED_VERSION=0
FORCE_32BIT_CROSS_COMPILE=0 FORCE_32BIT_CROSS_COMPILE=0
BUILD_MEGAGLEST_TESTS="ON"
while getopts "c:defhl:mnx" option; do while getopts "c:defhl:mnx" option; do
case "${option}" in case "${option}" in
@@ -34,7 +35,7 @@ while getopts "c:defhl:mnx" option; do
# echo "${option} value: ${OPTARG}" # echo "${option} value: ${OPTARG}"
;; ;;
e) e)
FORCE_EMBEDDED_LIBS="-DFORCE_EMBEDDED_LIBS=ON" FORCE_EMBEDDED_LIBS=1
# echo "${option} value: ${OPTARG}" # echo "${option} value: ${OPTARG}"
;; ;;
f) f)
@@ -47,9 +48,9 @@ while getopts "c:defhl:mnx" option; do
echo " option descriptions:" echo " option descriptions:"
echo " -c x : Force the cpu / cores count to x - example: -c 4" echo " -c x : Force the cpu / cores count to x - example: -c 4"
echo " -d : Force DYNAMIC compile (do not want static libs)" echo " -d : Force DYNAMIC compile (do not want static libs)"
echo " -e : Force EMBEDDED libraries compile" echo " -e : Force compile with EMBEDDED libraries"
echo " -f : Force using CLANG compiler" echo " -f : Force using CLANG compiler"
echo " -l x : Force using LUA version x - example: -l 51" echo " -l x : Force using LUA version x - example: -l 5.3"
echo " -m : Force running CMAKE only to create Make files (do not compile)" echo " -m : Force running CMAKE only to create Make files (do not compile)"
echo " -n : Force running MAKE only to compile (assume CMAKE already built make files)" echo " -n : Force running MAKE only to compile (assume CMAKE already built make files)"
echo " -x : Force cross compiling on x64 linux to produce an x86 32 bit binary" echo " -x : Force cross compiling on x64 linux to produce an x86 32 bit binary"
@@ -110,7 +111,7 @@ BREAKPAD_ROOT="$SCRIPTDIR/../../google-breakpad/"
# by our installers. # by our installers.
# For more cmake/build options refer to # For more cmake/build options refer to
# http://wiki.megaglest.org/Linux_Compiling#Building_using_CMake_by_Hand # http://wiki.megaglest.org/Linux_Compiling#Building_using_CMake_by_Hand
EXTRA_CMAKE_OPTIONS=-DWANT_USE_SDL2=ON EXTRA_CMAKE_OPTIONS=
# Build threads # Build threads
# By default we use all physical CPU cores to build. # By default we use all physical CPU cores to build.
@@ -144,14 +145,19 @@ detect_system
echo 'We have detected the following system:' echo 'We have detected the following system:'
echo ' [ '"$distribution"' ] [ '"$release"' ] [ '"$codename"' ] [ '"$architecture"' ]' echo ' [ '"$distribution"' ] [ '"$release"' ] [ '"$codename"' ] [ '"$architecture"' ]'
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFONTCONFIG_STATIC=OFF" if [ "$WANT_STATIC_LIBS" = "-DWANT_STATIC_LIBS=ON" ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DSTATIC_FONTCONFIG=OFF"
fi
case $distribution in case $distribution in
Debian) Debian)
case $release in case $release in
6.*|7.*) ;; 6.*|7.*) ;;
*) *)
echo 'Turning ON dynamic FTGL, LUA, JPEG, PNG ... and forcing use the embedded IRCCLIENT' if [ "$WANT_STATIC_LIBS" = "-DWANT_STATIC_LIBS=ON" ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFTGL_STATIC=OFF -DLUA_STATIC=OFF -DJPEG_STATIC=OFF -DPNG_STATIC=OFF -DOGG_STATIC=OFF -DFORCE_USE_EMBEDDED_IRCCLIENT=ON" echo 'Turning ON dynamic FTGL, LUA, JPEG, PNG ... and forcing use the embedded IRCCLIENT'
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DSTATIC_FTGL=OFF -DSTATIC_LUA=OFF -DSTATIC_JPEG=OFF -DSTATIC_PNG=OFF -DSTATIC_OGG=OFF -DFORCE_USE_EMBEDDED_Ircclient=ON"
fi
if [ $CLANG_FORCED = 1 ]; then BUILD_MEGAGLEST_TESTS="OFF"; fi
;; ;;
esac esac
;; ;;
@@ -160,9 +166,10 @@ case $distribution in
case $release in case $release in
10.*|11.*|12.*|13.*|14.*) ;; 10.*|11.*|12.*|13.*|14.*) ;;
*) *)
echo 'Turning ON dynamic FTGL, LUA, JPEG, PNG ... and forcing use the embedded IRCCLIENT' if [ "$WANT_STATIC_LIBS" = "-DWANT_STATIC_LIBS=ON" ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFTGL_STATIC=OFF -DLUA_STATIC=OFF -DJPEG_STATIC=OFF -DPNG_STATIC=OFF -DOGG_STATIC=OFF -DFORCE_USE_EMBEDDED_IRCCLIENT=ON" echo 'Turning ON dynamic FTGL, LUA, JPEG, PNG ... and forcing use the embedded IRCCLIENT'
;; EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DSTATIC_FTGL=OFF -DSTATIC_LUA=OFF -DSTATIC_JPEG=OFF -DSTATIC_PNG=OFF -DSTATIC_OGG=OFF -DFORCE_USE_EMBEDDED_Ircclient=ON"
fi;;
esac esac
;; ;;
@@ -170,33 +177,36 @@ case $distribution in
case $release in case $release in
13|13.*|14|15|16|17|17.*) ;; 13|13.*|14|15|16|17|17.*) ;;
*) *)
echo 'Turning ON dynamic FTGL, LUA, JPEG, PNG ... and forcing use the embedded IRCCLIENT' if [ "$WANT_STATIC_LIBS" = "-DWANT_STATIC_LIBS=ON" ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFTGL_STATIC=OFF -DLUA_STATIC=OFF -DJPEG_STATIC=OFF -DPNG_STATIC=OFF -DOGG_STATIC=OFF -DFORCE_USE_EMBEDDED_IRCCLIENT=ON" echo 'Turning ON dynamic FTGL, LUA, JPEG, PNG ... and forcing use the embedded IRCCLIENT'
;; EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DSTATIC_FTGL=OFF -DSTATIC_LUA=OFF -DSTATIC_JPEG=OFF -DSTATIC_PNG=OFF -DSTATIC_OGG=OFF -DFORCE_USE_EMBEDDED_Ircclient=ON"
fi;;
esac esac
;; ;;
SuSE|SUSE?LINUX|Opensuse) SuSE|SUSE?LINUX|Opensuse)
case $release in case $release in
*) *)
echo 'Turning ON dynamic CURL ...' if [ "$WANT_STATIC_LIBS" = "-DWANT_STATIC_LIBS=ON" ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFORCE_CURL_DYNAMIC_LIBS=ON" echo 'Turning ON dynamic CURL ...'
;; EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DSTATIC_CURL=OFF"
fi;;
esac esac
;; ;;
Fedora) Fedora)
case $release in case $release in
*) *)
echo 'Turning ON dynamic CURL ...' if [ "$WANT_STATIC_LIBS" = "-DWANT_STATIC_LIBS=ON" ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFORCE_CURL_DYNAMIC_LIBS=ON" echo 'Turning ON dynamic CURL ...'
;; EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DSTATIC_CURL=OFF"
fi;;
esac esac
;; ;;
Arch) Arch)
echo 'Turning ON dynamic LIBS ...' echo 'Turning ON dynamic LIBS ...'
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DWANT_STATIC_LIBS=OFF" WANT_STATIC_LIBS="-DWANT_STATIC_LIBS=OFF"
;; ;;
esac esac
@@ -226,18 +236,13 @@ elif [ "`echo $CC | grep -oF 'clang'`" = 'clang' -a "`echo $CXX | grep -oF 'clan
#exit 1; #exit 1;
fi fi
LUA_FORCED_CMAKE= if [ "$LUA_FORCED_VERSION" != "0" ] && [ "$LUA_FORCED_VERSION" != "" ]; then
if [ $LUA_FORCED_VERSION != 0 ]; then EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFORCE_LUA_VERSION=$LUA_FORCED_VERSION"
if [ $LUA_FORCED_VERSION = 53 ]; then #echo "USER WANTS TO FORCE USE of LUA $LUA_FORCED_VERSION"
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFORCE_LUA_5_3=ON" fi
echo "USER WANTS TO FORCE USE of LUA 5.3"
elif [ $LUA_FORCED_VERSION = 52 ]; then if [ "$FORCE_EMBEDDED_LIBS" != "0" ] && [ "$FORCE_EMBEDDED_LIBS" != "" ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFORCE_LUA_5_2=ON" EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFORCE_EMBEDDED_LIBS=ON"
echo "USER WANTS TO FORCE USE of LUA 5.2"
elif [ $LUA_FORCED_VERSION = 51 ]; then
EXTRA_CMAKE_OPTIONS="${EXTRA_CMAKE_OPTIONS} -DFORCE_LUA_5_1=ON"
echo "USER WANTS TO FORCE USE of LUA 5.1"
fi
fi fi
if [ $FORCE_32BIT_CROSS_COMPILE != 0 ]; then if [ $FORCE_32BIT_CROSS_COMPILE != 0 ]; then
@@ -250,7 +255,7 @@ fi
if [ $MAKE_ONLY = 0 ]; then if [ $MAKE_ONLY = 0 ]; then
echo "Calling cmake with EXTRA_CMAKE_OPTIONS = ${EXTRA_CMAKE_OPTIONS}" echo "Calling cmake with EXTRA_CMAKE_OPTIONS = ${EXTRA_CMAKE_OPTIONS}"
cmake -DCMAKE_INSTALL_PREFIX='' -DWANT_DEV_OUTPATH=ON $WANT_STATIC_LIBS $FORCE_EMBEDDED_LIBS -DBUILD_MEGAGLEST_TESTS=ON -DBREAKPAD_ROOT=$BREAKPAD_ROOT $EXTRA_CMAKE_OPTIONS ../../.. cmake -DCMAKE_INSTALL_PREFIX='' -DWANT_DEV_OUTPATH=ON $WANT_STATIC_LIBS -DBUILD_MEGAGLEST_TESTS=$BUILD_MEGAGLEST_TESTS -DBREAKPAD_ROOT=$BREAKPAD_ROOT $EXTRA_CMAKE_OPTIONS ../../..
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo 'ERROR: CMAKE failed.' >&2; exit 1 echo 'ERROR: CMAKE failed.' >&2; exit 1
fi fi
@@ -274,4 +279,3 @@ else
echo 'Or change into mk/linux and run it from there:' echo 'Or change into mk/linux and run it from there:'
echo ' ./megaglest --ini-path=./ --data-path=./' echo ' ./megaglest --ini-path=./ --data-path=./'
fi fi

View File

@@ -66,10 +66,10 @@ echo
echo '===== Updating Linux Installer ======' echo '===== Updating Linux Installer ======'
# local GAME_VERSION = "x.x.x"; # local GAME_VERSION = "x.x.x";
echo 'Linux Installer version # before:' echo 'Linux Installer version # before:'
grep -E '^local GAME_VERSION = "[^"]*";$' mojosetup/megaglest-installer/scripts/config.lua grep -E '^local GAME_VERSION = "[^"]*";$' tools-for-standalone-client/installer/scripts/config.lua
sed -i 's/^local GAME_VERSION = "[^"]*";$/local GAME_VERSION = "'$CURRENT_VERSION'";/' mojosetup/megaglest-installer/scripts/config.lua sed -i 's/^local GAME_VERSION = "[^"]*";$/local GAME_VERSION = "'$CURRENT_VERSION'";/' tools-for-standalone-client/installer/scripts/config.lua
echo 'Linux Installer version # after:' echo 'Linux Installer version # after:'
grep -E '^local GAME_VERSION = "[^"]*";$' mojosetup/megaglest-installer/scripts/config.lua grep -E '^local GAME_VERSION = "[^"]*";$' tools-for-standalone-client/installer/scripts/config.lua
echo echo
echo '===== Updating Windows Installer ======' echo '===== Updating Windows Installer ======'
# !define APVER 3.6.0 # !define APVER 3.6.0

View File

@@ -1,2 +0,0 @@
/build
/cmake-build

View File

@@ -1,846 +0,0 @@
# MojoSetup; a portable, flexible installation application.
#
# Please see the file LICENSE.txt in the source's root directory.
#
# This file written by Ryan C. Gordon.
# The "BINARY SIZE +=" comments note about how much bulk, in kilobytes, a
# given option adds to the binary on x86 Linux (built with gcc 3.3.6
# MinSizeRel options and stripped, uncompressed). These numbers will vary,
# and even on the original test system, become incorrect over time.
# Only choose options you want/need to squeeze every byte off the download.
# !!! FIXME: this is stupid.
IF(NOT BEOS)
IF(APPLE)
PROJECT(MojoSetup)
ELSE(APPLE)
PROJECT(MojoSetup C)
ENDIF(APPLE)
ELSE(NOT BEOS)
PROJECT(MojoSetup CXX)
ENDIF(NOT BEOS)
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.4)
# !!! FIXME: correct this to new policy and bump minimum cmake requirement.
IF(COMMAND CMAKE_POLICY)
# Use old policy when it comes to escaping macros,
# Specifically the one in quotes below.
CMAKE_POLICY(SET CMP0005 OLD)
ENDIF(COMMAND CMAKE_POLICY)
EXECUTE_PROCESS(
COMMAND hg tip --template hg-{rev}:{node|short}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE HGVERSION_RC
OUTPUT_VARIABLE MOJOSETUP_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
IF(HGVERSION_RC)
SET(MOJOSETUP_VERSION "???")
ENDIF(HGVERSION_RC)
# !!! FIXME: ditch this when Gary's curses patches go into a formal CMake
# !!! FIXME: release, and just bump the minimum required version to it.
# Search our own cmakemodules first.
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/misc")
# I hate that they define "WIN32" ... we're about to move to Win64...I hope!
IF(WIN32 AND NOT WINDOWS)
SET(WINDOWS TRUE)
ENDIF(WIN32 AND NOT WINDOWS)
# Bleh, let's do it for "APPLE" too.
IF(APPLE AND NOT MACOSX)
SET(MACOSX TRUE)
ENDIF(APPLE AND NOT MACOSX)
# And this might be wrong...
IF (CMAKE_SYSTEM MATCHES OS2)
SET(OS2 TRUE)
ENDIF (CMAKE_SYSTEM MATCHES OS2)
IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
SET(SOLARIS TRUE)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
INCLUDE(CheckIncludeFile)
INCLUDE(CheckLibraryExists)
INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckCCompilerFlag)
INCLUDE(TestBigEndian)
# See if C99 "restrict" keyword is available to us.
CHECK_C_SOURCE_COMPILES(
"int test_restrict(const char * restrict ptr); int main(void) { return 0; }"
MOJOSETUP_HAVE_RESTRICT_KEYWORD
)
IF(NOT MOJOSETUP_HAVE_RESTRICT_KEYWORD)
# See if __restrict__ keyword is available to us.
CHECK_C_SOURCE_COMPILES(
"int test_restrict(const char * __restrict__ ptr); int main(void) { return 0; }"
MOJOSETUP_HAVE_GNU_RESTRICT_KEYWORD
)
#IF(MOJOSETUP_HAVE_GNU_RESTRICT_KEYWORD)
# ADD_DEFINITIONS(-Drestrict=__restrict__)
#ELSE(MOJOSETUP_HAVE_GNU_RESTRICT_KEYWORD)
ADD_DEFINITIONS("-Drestrict=\"\"")
#ENDIF(MOJOSETUP_HAVE_GNU_RESTRICT_KEYWORD)
ENDIF(NOT MOJOSETUP_HAVE_RESTRICT_KEYWORD)
ADD_DEFINITIONS(-D__MOJOSETUP__=1)
ADD_DEFINITIONS(-DAPPID=mojosetup)
ADD_DEFINITIONS(-DAPPREV="${MOJOSETUP_VERSION}")
ADD_DEFINITIONS(-D_REENTRANT)
ADD_DEFINITIONS(-D_THREAD_SAFE)
INCLUDE_DIRECTORIES(.)
INCLUDE_DIRECTORIES(lua/src)
IF(WINDOWS)
ADD_DEFINITIONS(-DPLATFORM_WINDOWS=1)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS=1)
SET(USES_WINMAIN WIN32)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} shell32)
ENDIF(WINDOWS)
IF(MACOSX)
ADD_DEFINITIONS(-DPLATFORM_MACOSX=1)
IF(CMAKE_OSX_ARCHITECTURES MATCHES ppc)
ADD_DEFINITIONS(-DMAC_OS_X_VERSION_MIN_REQUIRED=1020)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} "-mmacosx-version-min=10.2")
ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES ppc)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} "-framework Carbon")
ENDIF(MACOSX)
IF(BEOS)
ADD_DEFINITIONS(-DPLATFORM_BEOS=1)
ENDIF(BEOS)
IF(UNIX)
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
ADD_DEFINITIONS(-DPLATFORM_UNIX=1)
ADD_DEFINITIONS(-DLUA_USE_MKSTEMP=1) # as opposed to tmpnam(), yuck!
# No _setjmp/_longjmp in BeOS 5 (or Haiku, at the moment).
IF(NOT BEOS)
ADD_DEFINITIONS(-DLUA_USE_ULONGJMP=1)
ENDIF(NOT BEOS)
ENDIF(UNIX)
IF(CMAKE_COMPILER_IS_GNUCC)
ADD_DEFINITIONS(-pipe -Wall -fsigned-char)
# See if -fvisibility=hidden is available to us.
CHECK_C_SOURCE_COMPILES("
#if ((defined(__GNUC__)) && (__GNUC__ >= 4))
int main(int argc, char **argv) { int is_gcc4 = 1; return 0; }
#else
#error This is not gcc4.
#endif
" MOJOSETUP_IS_GCC4)
IF(MOJOSETUP_IS_GCC4)
IF(NOT OS2 AND NOT SOLARIS) # Not supported on OS/2 or Solaris.
ADD_DEFINITIONS(-fvisibility=hidden)
ENDIF(NOT OS2 AND NOT SOLARIS)
ENDIF(MOJOSETUP_IS_GCC4)
# See if -fno-stack-protector is available to us.
# It doesn't seem to work well, and it adds bulk to the binary.
CHECK_C_COMPILER_FLAG("-fno-stack-protector" MOJOSETUP_GCC_HAS_STACKPROT)
IF(MOJOSETUP_GCC_HAS_STACKPROT)
ADD_DEFINITIONS(-fno-stack-protector)
ENDIF(MOJOSETUP_GCC_HAS_STACKPROT)
# !!! FIXME: probably not safe long-term.
# CMake mailing list had this hack for getting rid of -rdynamic:
# http://public.kitware.com/pipermail/cmake/2006-July/010404.html
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Don't use -rpath.
SET(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE)
ENDIF(CMAKE_COMPILER_IS_GNUCC)
IF(CMAKE_C_COMPILER_ID STREQUAL "SunPro")
ADD_DEFINITIONS(-erroff=E_EMPTY_TRANSLATION_UNIT)
ADD_DEFINITIONS(-xldscope=hidden)
ENDIF(CMAKE_C_COMPILER_ID STREQUAL "SunPro")
TEST_BIG_ENDIAN(MOJOSETUP_IS_BIGENDIAN)
IF(MOJOSETUP_IS_BIGENDIAN)
ADD_DEFINITIONS(-DPLATFORM_BIGENDIAN=1)
ELSE(MOJOSETUP_IS_BIGENDIAN)
ADD_DEFINITIONS(-DPLATFORM_LITTLEENDIAN=1)
ENDIF(MOJOSETUP_IS_BIGENDIAN)
SET(BZLIB_DIR bzip2)
SET(BZLIB_SRCS
${BZLIB_DIR}/blocksort.c
${BZLIB_DIR}/huffman.c
${BZLIB_DIR}/crctable.c
${BZLIB_DIR}/randtable.c
${BZLIB_DIR}/compress.c
${BZLIB_DIR}/decompress.c
${BZLIB_DIR}/bzlib.c
)
SET(LIBLZMA_DIR liblzma)
SET(LIBLZMA_SRCS
${LIBLZMA_DIR}/check/check.c
${LIBLZMA_DIR}/common/block_buffer_decoder.c
${LIBLZMA_DIR}/common/block_decoder.c
${LIBLZMA_DIR}/common/block_header_decoder.c
${LIBLZMA_DIR}/common/block_util.c
${LIBLZMA_DIR}/common/common.c
${LIBLZMA_DIR}/common/easy_decoder_memusage.c
${LIBLZMA_DIR}/common/easy_preset.c
${LIBLZMA_DIR}/common/filter_buffer_decoder.c
${LIBLZMA_DIR}/common/filter_common.c
${LIBLZMA_DIR}/common/filter_decoder.c
${LIBLZMA_DIR}/common/filter_flags_decoder.c
${LIBLZMA_DIR}/common/index.c
${LIBLZMA_DIR}/common/index_decoder.c
${LIBLZMA_DIR}/common/index_hash.c
${LIBLZMA_DIR}/common/stream_decoder.c
${LIBLZMA_DIR}/common/stream_flags_common.c
${LIBLZMA_DIR}/common/stream_flags_decoder.c
${LIBLZMA_DIR}/common/vli_decoder.c
${LIBLZMA_DIR}/common/vli_size.c
${LIBLZMA_DIR}/delta/delta_common.c
${LIBLZMA_DIR}/delta/delta_decoder.c
${LIBLZMA_DIR}/lz/lz_decoder.c
${LIBLZMA_DIR}/lzma/lzma2_decoder.c
${LIBLZMA_DIR}/lzma/lzma_decoder.c
${LIBLZMA_DIR}/lzma/lzma_encoder_presets.c
${LIBLZMA_DIR}/simple/arm.c
${LIBLZMA_DIR}/simple/armthumb.c
${LIBLZMA_DIR}/simple/ia64.c
${LIBLZMA_DIR}/simple/powerpc.c
${LIBLZMA_DIR}/simple/simple_coder.c
${LIBLZMA_DIR}/simple/simple_decoder.c
${LIBLZMA_DIR}/simple/sparc.c
${LIBLZMA_DIR}/simple/x86.c
)
SET(LIBFETCH_DIR libfetch)
SET(LIBFETCH_SRCS
${LIBFETCH_DIR}/fetch.c
${LIBFETCH_DIR}/common.c
${LIBFETCH_DIR}/ftp.c
${LIBFETCH_DIR}/http.c
)
SET(LUA_DIR lua)
SET(LUA_SRCS
${LUA_DIR}/src/lapi.c
${LUA_DIR}/src/ldebug.c
${LUA_DIR}/src/ldo.c
${LUA_DIR}/src/ldump.c
${LUA_DIR}/src/lfunc.c
${LUA_DIR}/src/lgc.c
${LUA_DIR}/src/lmem.c
${LUA_DIR}/src/lobject.c
${LUA_DIR}/src/lopcodes.c
${LUA_DIR}/src/lstate.c
${LUA_DIR}/src/lstring.c
${LUA_DIR}/src/ltable.c
${LUA_DIR}/src/ltm.c
${LUA_DIR}/src/lundump.c
${LUA_DIR}/src/lvm.c
${LUA_DIR}/src/lzio.c
${LUA_DIR}/src/lauxlib.c
${LUA_DIR}/src/lbaselib.c
${LUA_DIR}/src/lstrlib.c
${LUA_DIR}/src/ltablib.c
${LUA_DIR}/src/lctype.c
)
SET(LUA_PARSER_SRCS
${LUA_DIR}/src/lparser.c
${LUA_DIR}/src/llex.c
${LUA_DIR}/src/lcode.c
)
SET(MOJOSETUP_SRCS
buildver.c
mojosetup.c
gui.c
fileio.c
archive_zip.c
archive_tar.c
archive_uz2.c
archive_pck.c
archive_pkg.c
checksum_crc32.c
checksum_md5.c
checksum_sha1.c
platform_unix.c
platform_windows.c
lua_glue.c
${LUA_SRCS}
)
# Have to separate this, so CMake doesn't try to link in C++ support on other
# platforms.
IF(BEOS)
SET(MOJOSETUP_SRCS ${MOJOSETUP_SRCS} platform_beos.cpp)
ENDIF(BEOS)
SET(MOJOLUAC_SRCS
${LUA_SRCS}
${LUA_PARSER_SRCS}
${LUA_DIR}/src/luac.c
${LUA_DIR}/src/linit.c
${LUA_DIR}/src/lctype.c
${LUA_DIR}/src/ldblib.c
${LUA_DIR}/src/liolib.c
${LUA_DIR}/src/lmathlib.c
${LUA_DIR}/src/loslib.c
${LUA_DIR}/src/lbitlib.c
${LUA_DIR}/src/lcorolib.c
${LUA_DIR}/src/loadlib.c
)
SET(STBIMAGE_SRCS
stb_image.c
)
# Disabling the parser cuts the Lua binary bits by about 35%, plus .luac files
# are almost always smaller than the original scripts. The downside is you
# (and end users in the field) can't just tweak a script without recompiling
# it, but even that's not an unclimbable obstacle.
# In reality, you probably want to keep the parser, though, unless you REALLY
# must save every single byte in the download.
# YOU NEED THE PARSER IF YOU WANT MANIFESTS WRITTEN OUT.
# YOU NEED THE PARSER IF YOU WANT THE UNINSTALLER TO WORK.
# DON'T DISABLE THIS NOW IF YOU DON'T ABSOLUTELY HAVE TO.
# BINARY SIZE += 19
OPTION(MOJOSETUP_LUA_PARSER "Bigger binary but scripts don't need to be compiled." TRUE)
IF(MOJOSETUP_LUA_PARSER)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LUA_PARSER_SRCS})
ELSE(MOJOSETUP_LUA_PARSER)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LUA_DIR}/etc/noparser.c)
ADD_DEFINITIONS(-DDISABLE_LUA_PARSER=1)
ENDIF(MOJOSETUP_LUA_PARSER)
# Kludge for Linux x86/amd64 bins...
IF(UNIX AND NOT MACOSX) # Just use Mach-O Universal/"fat" binaries on OS X.
OPTION(MOJOSETUP_MULTIARCH "Allow multiarch hack." FALSE)
MARK_AS_ADVANCED(MOJOSETUP_MULTIARCH)
IF(MOJOSETUP_MULTIARCH)
ADD_DEFINITIONS(-DSUPPORT_MULTIARCH=1)
ENDIF(MOJOSETUP_MULTIARCH)
ENDIF(UNIX AND NOT MACOSX)
# Optional bits of the Lua runtime library...
# BINARY SIZE += 4.5
OPTION(MOJOSETUP_LUALIB_IO "Add Lua 'io' library" TRUE)
MARK_AS_ADVANCED(MOJOSETUP_LUALIB_IO)
IF(MOJOSETUP_LUALIB_IO)
ADD_DEFINITIONS(-DSUPPORT_LUALIB_IO=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LUA_DIR}/src/liolib.c)
ENDIF(MOJOSETUP_LUALIB_IO)
# BINARY SIZE += 2.5
OPTION(MOJOSETUP_LUALIB_OS "Add Lua 'os' library" TRUE)
MARK_AS_ADVANCED(MOJOSETUP_LUALIB_OS)
IF(MOJOSETUP_LUALIB_OS)
ADD_DEFINITIONS(-DSUPPORT_LUALIB_OS=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LUA_DIR}/src/loslib.c)
ENDIF(MOJOSETUP_LUALIB_OS)
# BINARY SIZE += 3.5
OPTION(MOJOSETUP_LUALIB_MATH "Add Lua 'math' library" TRUE)
MARK_AS_ADVANCED(MOJOSETUP_LUALIB_MATH)
IF(MOJOSETUP_LUALIB_MATH)
ADD_DEFINITIONS(-DSUPPORT_LUALIB_MATH=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LUA_DIR}/src/lmathlib.c)
ENDIF(MOJOSETUP_LUALIB_MATH)
# BINARY SIZE += 3.5
OPTION(MOJOSETUP_LUALIB_DB "Add Lua 'db' library" TRUE)
MARK_AS_ADVANCED(MOJOSETUP_LUALIB_DB)
IF(MOJOSETUP_LUALIB_DB)
ADD_DEFINITIONS(-DSUPPORT_LUALIB_DB=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LUA_DIR}/src/ldblib.c)
ENDIF(MOJOSETUP_LUALIB_DB)
# BINARY SIZE += 4
OPTION(MOJOSETUP_LUALIB_PACKAGE "Add Lua 'package' library" TRUE)
MARK_AS_ADVANCED(MOJOSETUP_LUALIB_PACKAGE)
IF(MOJOSETUP_LUALIB_PACKAGE)
ADD_DEFINITIONS(-DSUPPORT_LUALIB_PACKAGE=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LUA_DIR}/src/loadlib.c)
ENDIF(MOJOSETUP_LUALIB_PACKAGE)
# BINARY SIZE += ?
OPTION(MOJOSETUP_LUALIB_BIT "Add Lua 'bit' library" TRUE)
MARK_AS_ADVANCED(MOJOSETUP_LUALIB_BIT)
IF(MOJOSETUP_LUALIB_BIT)
ADD_DEFINITIONS(-DSUPPORT_LUALIB_BIT=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LUA_DIR}/src/lbitlib.c)
ENDIF(MOJOSETUP_LUALIB_BIT)
# BINARY SIZE += ?
OPTION(MOJOSETUP_LUALIB_CORO "Add Lua 'coro' library" TRUE)
MARK_AS_ADVANCED(MOJOSETUP_LUALIB_CORO)
IF(MOJOSETUP_LUALIB_CORO)
ADD_DEFINITIONS(-DSUPPORT_LUALIB_CORO=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LUA_DIR}/src/lcorolib.c)
ENDIF(MOJOSETUP_LUALIB_CORO)
# Checksums...
# BINARY SIZE += !!! FIXME: check this.
OPTION(MOJOSETUP_CHECKSUM_CRC32 "Enable CRC-32 checksum support" TRUE)
IF(MOJOSETUP_CHECKSUM_CRC32)
ADD_DEFINITIONS(-DSUPPORT_CRC32=1)
ENDIF(MOJOSETUP_CHECKSUM_CRC32)
# BINARY SIZE += !!! FIXME: check this.
OPTION(MOJOSETUP_CHECKSUM_MD5 "Enable MD5 checksum support" TRUE)
IF(MOJOSETUP_CHECKSUM_MD5)
ADD_DEFINITIONS(-DSUPPORT_MD5=1)
ENDIF(MOJOSETUP_CHECKSUM_MD5)
# BINARY SIZE += !!! FIXME: check this.
OPTION(MOJOSETUP_CHECKSUM_SHA1 "Enable SHA-1 checksum support" TRUE)
IF(MOJOSETUP_CHECKSUM_SHA1)
ADD_DEFINITIONS(-DSUPPORT_SHA1=1)
ENDIF(MOJOSETUP_CHECKSUM_SHA1)
# GUI plugins...
MACRO(MOJOSETUP_ADD_LIBRARY _TARGET _SRCS)
ADD_LIBRARY(${_TARGET} SHARED ${_SRCS})
SET(MOJOSETUP_TARGETS "${MOJOSETUP_TARGETS};${_TARGET}")
ENDMACRO(MOJOSETUP_ADD_LIBRARY)
# BINARY SIZE += 2.5
OPTION(MOJOSETUP_GUI_STDIO "Enable stdio GUI" TRUE)
IF(MOJOSETUP_GUI_STDIO)
ADD_DEFINITIONS(-DSUPPORT_GUI_STDIO=1)
OPTION(MOJOSETUP_GUI_STDIO_STATIC "Statically link stdio GUI" TRUE)
IF(MOJOSETUP_GUI_STDIO_STATIC)
ADD_DEFINITIONS(-DGUI_STATIC_LINK_STDIO=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} gui_stdio.c)
ELSE(MOJOSETUP_GUI_STDIO_STATIC)
MOJOSETUP_ADD_LIBRARY(mojosetupgui_stdio gui_stdio.c)
ENDIF(MOJOSETUP_GUI_STDIO_STATIC)
ENDIF(MOJOSETUP_GUI_STDIO)
# BINARY SIZE += !!! FIXME: check this.
SET(CURSES_NEED_WIDE TRUE)
SET(CURSES_NEED_NCURSES TRUE)
FIND_PACKAGE(Curses)
IF(CURSES_FOUND)
OPTION(MOJOSETUP_GUI_NCURSES "Enable ncurses GUI" TRUE)
IF(MOJOSETUP_GUI_NCURSES)
ADD_DEFINITIONS(-DSUPPORT_GUI_NCURSES=1)
INCLUDE_DIRECTORIES(CURSES_INCLUDE_DIR)
IF(CURSES_HAVE_NCURSESW_NCURSES_H)
ADD_DEFINITIONS(-DHAVE_NCURSESW_NCURSES_H)
ELSEIF(CURSES_HAVE_NCURSESW_CURSES_H)
ADD_DEFINITIONS(-DHAVE_NCURSESW_CURSES_H)
ELSEIF(CURSES_HAVE_NCURSESW_H)
ADD_DEFINITIONS(-DHAVE_NCURSESW_H)
ENDIF(CURSES_HAVE_NCURSESW_NCURSES_H)
OPTION(MOJOSETUP_GUI_NCURSES_STATIC "Statically link ncurses GUI" FALSE)
IF(MOJOSETUP_GUI_NCURSES_STATIC)
ADD_DEFINITIONS(-DGUI_STATIC_LINK_NCURSES=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} gui_ncurses.c)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} ${CURSES_LIBRARIES})
ELSE(MOJOSETUP_GUI_NCURSES_STATIC)
MOJOSETUP_ADD_LIBRARY(mojosetupgui_ncurses gui_ncurses.c)
TARGET_LINK_LIBRARIES(mojosetupgui_ncurses ${CURSES_LIBRARIES})
ENDIF(MOJOSETUP_GUI_NCURSES_STATIC)
ENDIF(MOJOSETUP_GUI_NCURSES)
ENDIF(CURSES_FOUND)
IF(MACOSX)
OPTION(MOJOSETUP_GUI_COCOA "Enable Cocoa GUI" TRUE)
IF(MOJOSETUP_GUI_COCOA)
ADD_DEFINITIONS(-DSUPPORT_GUI_COCOA=1)
OPTION(MOJOSETUP_GUI_COCOA_STATIC "Statically link Cocoa GUI" TRUE)
IF(MOJOSETUP_GUI_COCOA_STATIC)
ADD_DEFINITIONS(-DGUI_STATIC_LINK_COCOA=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} gui_cocoa.m)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} "-framework Cocoa")
ELSE(MOJOSETUP_GUI_COCOA_STATIC)
MOJOSETUP_ADD_LIBRARY(mojosetupgui_cocoa gui_cocoa.m)
TARGET_LINK_LIBRARIES(mojosetupgui_cocoa
"-framework Carbon -framework Cocoa -mmacosx-version-min=10.2"
)
ENDIF(MOJOSETUP_GUI_COCOA_STATIC)
ENDIF(MOJOSETUP_GUI_COCOA)
ENDIF(MACOSX)
IF(UNIX)
IF(NOT BEOS)
IF(NOT MACOSX)
#FIND_PACKAGE(PkgConfig)
#PKGCONFIG(libgtk-2.0 LIBGTK_INCLUDE_DIR LIBGTK_LINK_DIR LIBGTK_LINK_FLAGS LIBGTK_CFLAGS)
# !!! FIXME
SET(LIBGTK_LINK_FLAGS "-lgtk-x11-2.0 -lgdk-x11-2.0 -lgmodule-2.0 -ldl -lgobject-2.0 -lglib-2.0 -lgdk_pixbuf-2.0 -lgio-2.0")
SET(LIBGTK_CFLAGS "-DPNG_NO_MMX_CODE `pkg-config --cflags --libs gtk+-2.0` -I/usr/include/atk-1.0 `pkg-config --cflags --libs gdk-2.0` -I/usr/include/cairo -I/usr/include/pango-1.0 `pkg-config --cflags --libs glib-2.0` -I/usr/include/freetype2 -I/usr/include/libpng12")
IF(NOT LIBGTK_LINK_FLAGS)
MESSAGE(STATUS "Can't find GTK+v2 headers/libraries. Can't build GTK+ GUI.")
ELSE(NOT LIBGTK_LINK_FLAGS)
OPTION(MOJOSETUP_GUI_GTKPLUS2 "Enable GTK+ 2.0 GUI" TRUE)
IF(MOJOSETUP_GUI_GTKPLUS2)
ADD_DEFINITIONS(-DSUPPORT_GUI_GTKPLUS2=1)
#INCLUDE_DIRECTORIES(${LIBGTK_INCLUDE_DIR})
OPTION(MOJOSETUP_GUI_GTKPLUS2_STATIC "Statically link GTK+ GUI" FALSE)
IF(MOJOSETUP_GUI_GTKPLUS2_STATIC)
ADD_DEFINITIONS(-DGUI_STATIC_LINK_GTKPLUS2=1 ${LIBGTK_CFLAGS})
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} gui_gtkplus2.c)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} ${LIBGTK_LINK_FLAGS})
ELSE(MOJOSETUP_GUI_GTKPLUS2_STATIC)
MOJOSETUP_ADD_LIBRARY(mojosetupgui_gtkplus2 gui_gtkplus2.c)
ADD_DEFINITIONS(${LIBGTK_CFLAGS})
TARGET_LINK_LIBRARIES(mojosetupgui_gtkplus2 ${LIBGTK_LINK_FLAGS})
ENDIF(MOJOSETUP_GUI_GTKPLUS2_STATIC)
ENDIF(MOJOSETUP_GUI_GTKPLUS2)
ENDIF(NOT LIBGTK_LINK_FLAGS)
ENDIF(NOT MACOSX)
ENDIF(NOT BEOS)
ENDIF(UNIX)
# BINARY SIZE += !!! FIXME: check this.
OPTION(MOJOSETUP_GUI_WWW "Enable www GUI" FALSE) # !!! FIXME: make TRUE
IF(MOJOSETUP_GUI_WWW)
ADD_DEFINITIONS(-DSUPPORT_GUI_WWW=1)
OPTION(MOJOSETUP_GUI_WWW_STATIC "Statically link www GUI" FALSE)
IF(MOJOSETUP_GUI_WWW_STATIC)
ADD_DEFINITIONS(-DGUI_STATIC_LINK_WWW=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} gui_www.c)
IF(WINDOWS)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} wsock32)
ENDIF(WINDOWS)
ELSE(MOJOSETUP_GUI_WWW_STATIC)
MOJOSETUP_ADD_LIBRARY(mojosetupgui_www gui_www.c)
IF(WINDOWS)
TARGET_LINK_LIBRARIES(mojosetupgui_www wsock32)
ENDIF(WINDOWS)
ENDIF(MOJOSETUP_GUI_WWW_STATIC)
SET(MOJOSETUP_USES_SOCKETS TRUE)
ENDIF(MOJOSETUP_GUI_WWW)
# Archivers...
# BINARY SIZE += 8
OPTION(MOJOSETUP_ARCHIVE_ZIP "Enable ZIP support" TRUE)
IF(MOJOSETUP_ARCHIVE_ZIP)
ADD_DEFINITIONS(-DSUPPORT_ZIP=1)
SET(MOJOSETUP_NEED_ZLIB TRUE)
ENDIF(MOJOSETUP_ARCHIVE_ZIP)
# BINARY SIZE += 2
OPTION(MOJOSETUP_ARCHIVE_TAR "Enable TAR support" TRUE)
IF(MOJOSETUP_ARCHIVE_TAR)
# !!! FIXME: the gzip/bzip2/xz support doesn't require .tar archives now.
# !!! FIXME: Maybe not ask here, so the questions look the same everywhere.
ADD_DEFINITIONS(-DSUPPORT_TAR=1)
OPTION(MOJOSETUP_ARCHIVE_TAR_GZ "Enable TAR.GZ support" TRUE)
IF(MOJOSETUP_ARCHIVE_TAR_GZ)
SET(MOJOSETUP_INPUT_GZIP TRUE)
ENDIF(MOJOSETUP_ARCHIVE_TAR_GZ)
OPTION(MOJOSETUP_ARCHIVE_TAR_BZ2 "Enable TAR.BZ2 support" TRUE)
IF(MOJOSETUP_ARCHIVE_TAR_BZ2)
SET(MOJOSETUP_INPUT_BZIP2 TRUE)
ENDIF(MOJOSETUP_ARCHIVE_TAR_BZ2)
OPTION(MOJOSETUP_ARCHIVE_TAR_XZ "Enable TAR.XZ support" TRUE)
IF(MOJOSETUP_ARCHIVE_TAR_XZ)
SET(MOJOSETUP_INPUT_XZ TRUE)
ENDIF(MOJOSETUP_ARCHIVE_TAR_XZ)
ENDIF(MOJOSETUP_ARCHIVE_TAR)
OPTION(MOJOSETUP_ARCHIVE_UZ2 "Enable UZ2 support" FALSE)
IF(MOJOSETUP_ARCHIVE_UZ2)
ADD_DEFINITIONS(-DSUPPORT_UZ2=1)
SET(MOJOSETUP_NEED_ZLIB TRUE)
ENDIF(MOJOSETUP_ARCHIVE_UZ2)
OPTION(MOJOSETUP_ARCHIVE_PCK "Enable PCK support" FALSE)
IF(MOJOSETUP_ARCHIVE_PCK)
ADD_DEFINITIONS(-DSUPPORT_PCK=1)
SET(MOJOSETUP_INPUT_GZIP TRUE)
ENDIF(MOJOSETUP_ARCHIVE_PCK)
OPTION(MOJOSETUP_ARCHIVE_PKG "Enable PKG support" FALSE)
IF(MOJOSETUP_ARCHIVE_PKG)
ADD_DEFINITIONS(-DSUPPORT_PKG=1)
ENDIF(MOJOSETUP_ARCHIVE_PKG)
# Input decoders...
# BINARY SIZE += 1.5
IF(NOT MOJOSETUP_INPUT_GZIP) # optional if something didn't force it.
OPTION(MOJOSETUP_INPUT_GZIP "Enable GZIP support" FALSE)
ENDIF(NOT MOJOSETUP_INPUT_GZIP)
IF(MOJOSETUP_INPUT_GZIP)
ADD_DEFINITIONS(-DSUPPORT_GZIP=1)
SET(MOJOSETUP_NEED_ZLIB TRUE)
ENDIF(MOJOSETUP_INPUT_GZIP)
# BINARY SIZE += 1.5
IF(NOT MOJOSETUP_INPUT_BZIP2) # optional if something didn't force it.
OPTION(MOJOSETUP_INPUT_BZIP2 "Enable BZIP2 support" FALSE)
ENDIF(NOT MOJOSETUP_INPUT_BZIP2)
IF(MOJOSETUP_INPUT_BZIP2)
ADD_DEFINITIONS(-DSUPPORT_BZIP2=1)
ADD_DEFINITIONS(-DBZ_NO_STDIO=1)
SET(MOJOSETUP_NEED_BZLIB TRUE)
ENDIF(MOJOSETUP_INPUT_BZIP2)
# BINARY SIZE += ???
IF(NOT MOJOSETUP_INPUT_XZ) # optional if something didn't force it.
OPTION(MOJOSETUP_INPUT_XZ "Enable XZ support" FALSE)
ENDIF(NOT MOJOSETUP_INPUT_XZ)
IF(MOJOSETUP_INPUT_XZ)
ADD_DEFINITIONS(-DSUPPORT_XZ=1)
SET(MOJOSETUP_NEED_LIBLZMA TRUE)
ENDIF(MOJOSETUP_INPUT_XZ)
# Image decoders for GUIs...
OPTION(MOJOSETUP_IMAGE_JPG "Enable JPG support" TRUE)
IF(MOJOSETUP_IMAGE_JPG)
ADD_DEFINITIONS(-DSUPPORT_JPG=1)
SET(MOJOSETUP_NEED_STBIMAGE TRUE)
ENDIF(MOJOSETUP_IMAGE_JPG)
OPTION(MOJOSETUP_IMAGE_PNG "Enable PNG support" TRUE)
IF(MOJOSETUP_IMAGE_PNG)
ADD_DEFINITIONS(-DSUPPORT_PNG=1)
SET(MOJOSETUP_NEED_STBIMAGE TRUE)
ENDIF(MOJOSETUP_IMAGE_PNG)
OPTION(MOJOSETUP_IMAGE_TGA "Enable TGA support" FALSE)
IF(MOJOSETUP_IMAGE_TGA)
ADD_DEFINITIONS(-DSUPPORT_TGA=1)
SET(MOJOSETUP_NEED_STBIMAGE TRUE)
ENDIF(MOJOSETUP_IMAGE_TGA)
OPTION(MOJOSETUP_IMAGE_BMP "Enable BMP support" FALSE)
IF(MOJOSETUP_IMAGE_BMP)
ADD_DEFINITIONS(-DSUPPORT_BMP=1)
SET(MOJOSETUP_NEED_STBIMAGE TRUE)
ENDIF(MOJOSETUP_IMAGE_BMP)
OPTION(MOJOSETUP_IMAGE_PSD "Enable PSD support" FALSE)
IF(MOJOSETUP_IMAGE_PSD)
ADD_DEFINITIONS(-DSUPPORT_PSD=1)
SET(MOJOSETUP_NEED_STBIMAGE TRUE)
ENDIF(MOJOSETUP_IMAGE_PSD)
OPTION(MOJOSETUP_IMAGE_HDR "Enable HDR support" FALSE)
IF(MOJOSETUP_IMAGE_HDR)
ADD_DEFINITIONS(-DSUPPORT_HDR=1)
SET(MOJOSETUP_NEED_STBIMAGE TRUE)
ENDIF(MOJOSETUP_IMAGE_HDR)
IF(MOJOSETUP_NEED_STBIMAGE)
ADD_DEFINITIONS(-DSUPPORT_STBIMAGE=1)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${STBIMAGE_SRCS})
ENDIF(MOJOSETUP_NEED_STBIMAGE)
# Networking...
# BINARY SIZE += 5 ...plus libfetch
OPTION(MOJOSETUP_URL_HTTP "Enable http:// support" TRUE)
IF(MOJOSETUP_URL_HTTP)
ADD_DEFINITIONS(-DSUPPORT_URL_HTTP=1)
SET(MOJOSETUP_NEED_LIBFETCH TRUE)
ENDIF(MOJOSETUP_URL_HTTP)
# BINARY SIZE += 9 ...plus libfetch
OPTION(MOJOSETUP_URL_FTP "Enable ftp:// support" TRUE)
IF(MOJOSETUP_URL_FTP)
ADD_DEFINITIONS(-DSUPPORT_URL_FTP=1)
SET(MOJOSETUP_NEED_LIBFETCH TRUE)
ENDIF(MOJOSETUP_URL_FTP)
# BINARY SIZE += 10
IF(MOJOSETUP_NEED_LIBFETCH)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LIBFETCH_SRCS})
# Had to spin up some threads in libfetch...lame.
# !!! FIXME: CMake will do -lpthread on Mac OS X, but it doesn't need it.
IF(NOT MACOSX)
FIND_PACKAGE(Threads)
ENDIF(NOT MACOSX)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
SET(MOJOSETUP_USES_SOCKETS TRUE)
ENDIF(MOJOSETUP_NEED_LIBFETCH)
IF(MOJOSETUP_USES_SOCKETS)
IF(SOLARIS)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} "socket")
ENDIF(SOLARIS)
ENDIF(MOJOSETUP_USES_SOCKETS)
# Middleware...
IF(MOJOSETUP_NEED_ZLIB)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} miniz.c)
ENDIF(MOJOSETUP_NEED_ZLIB)
IF(MOJOSETUP_NEED_BZLIB)
SET(HAVE_SYSTEM_BZLIB FALSE)
CHECK_INCLUDE_FILE(bzlib.h HAVE_BZLIB_H)
IF(HAVE_BZLIB_H)
CHECK_LIBRARY_EXISTS("bz2" "BZ2_bzDecompress" "" HAVE_LIBBZ2)
IF(HAVE_LIBBZ2)
SET(HAVE_SYSTEM_BZLIB TRUE)
ENDIF(HAVE_LIBBZ2)
ENDIF(HAVE_BZLIB_H)
IF(HAVE_SYSTEM_BZLIB)
OPTION(MOJOSETUP_INTERNAL_BZLIB "Link own bzlib instead of system library" FALSE)
ELSE(HAVE_SYSTEM_BZLIB)
SET(MOJOSETUP_INTERNAL_BZLIB TRUE)
ENDIF(HAVE_SYSTEM_BZLIB)
# BINARY SIZE += 46
IF(MOJOSETUP_INTERNAL_BZLIB)
ADD_DEFINITIONS(-DMOJOSETUP_INTERNAL_BZLIB=1)
INCLUDE_DIRECTORIES(${BZLIB_DIR})
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${BZLIB_SRCS})
ELSE(MOJOSETUP_INTERNAL_BZLIB)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} bz2)
ENDIF(MOJOSETUP_INTERNAL_BZLIB)
ENDIF(MOJOSETUP_NEED_BZLIB)
IF(MOJOSETUP_NEED_LIBLZMA)
SET(HAVE_SYSTEM_LIBLZMA FALSE)
CHECK_INCLUDE_FILE(lzma.h HAVE_LZMA_H)
IF(HAVE_LZMA_H)
CHECK_LIBRARY_EXISTS("lzma" "lzma_stream_decoder" "" HAVE_LIBLZMA)
IF(HAVE_LIBLZMA)
SET(HAVE_SYSTEM_LIBLZMA TRUE)
ENDIF(HAVE_LIBLZMA)
ENDIF(HAVE_LZMA_H)
IF(HAVE_SYSTEM_LIBLZMA)
OPTION(MOJOSETUP_INTERNAL_LIBLZMA "Link own liblzma instead of system library" FALSE)
ELSE(HAVE_SYSTEM_LIBLZMA)
SET(MOJOSETUP_INTERNAL_LIBLZMA TRUE)
ENDIF(HAVE_SYSTEM_LIBLZMA)
# BINARY SIZE += ???
IF(MOJOSETUP_INTERNAL_LIBLZMA)
ADD_DEFINITIONS(-DMOJOSETUP_INTERNAL_LIBLZMA=1)
INCLUDE_DIRECTORIES(${LIBLZMA_DIR}/api)
INCLUDE_DIRECTORIES(${LIBLZMA_DIR}/common)
INCLUDE_DIRECTORIES(${LIBLZMA_DIR}/check)
INCLUDE_DIRECTORIES(${LIBLZMA_DIR}/delta)
INCLUDE_DIRECTORIES(${LIBLZMA_DIR}/lz)
INCLUDE_DIRECTORIES(${LIBLZMA_DIR}/lzma)
INCLUDE_DIRECTORIES(${LIBLZMA_DIR}/rangecoder)
INCLUDE_DIRECTORIES(${LIBLZMA_DIR}/simple)
SET(OPTIONAL_SRCS ${OPTIONAL_SRCS} ${LIBLZMA_SRCS})
ELSE(MOJOSETUP_INTERNAL_LIBLZMA)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} lzma)
ENDIF(MOJOSETUP_INTERNAL_LIBLZMA)
ENDIF(MOJOSETUP_NEED_LIBLZMA)
IF(UNIX)
CHECK_INCLUDE_FILE(sys/ucred.h HAVE_UCRED_H)
IF(HAVE_UCRED_H)
ADD_DEFINITIONS(-DMOJOSETUP_HAVE_SYS_UCRED_H=1)
ENDIF(HAVE_UCRED_H)
CHECK_INCLUDE_FILE(mntent.h HAVE_MNTENT_H)
IF(HAVE_MNTENT_H)
ADD_DEFINITIONS(-DMOJOSETUP_HAVE_MNTENT_H=1)
ENDIF(HAVE_MNTENT_H)
# !!! FIXME: Solaris fails this, because mnttab.h implicitly
# !!! FIXME: depends on other system headers. :(
#CHECK_INCLUDE_FILE(sys/mnttab.h HAVE_SYS_MNTTAB_H)
CHECK_C_SOURCE_COMPILES("
#include <stdio.h>
#include <sys/mnttab.h>
int main(int argc, char **argv) { return 0; }
" HAVE_SYS_MNTTAB_H)
IF(HAVE_SYS_MNTTAB_H)
ADD_DEFINITIONS(-DMOJOSETUP_HAVE_SYS_MNTTAB_H=1)
ENDIF(HAVE_SYS_MNTTAB_H)
IF(NOT MACOSX)
CHECK_LIBRARY_EXISTS("dl" "dlopen" "" HAVE_LIBDL)
IF(HAVE_LIBDL)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} dl)
ENDIF(HAVE_LIBDL)
CHECK_LIBRARY_EXISTS("m" "sin" "" HAVE_LIBM)
IF(HAVE_LIBM)
SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} m)
ENDIF(HAVE_LIBM)
ENDIF(NOT MACOSX)
ENDIF(UNIX)
OPTION(MOJOSETUP_BUILD_LUAC "Build separate Lua compiler" TRUE)
IF(MOJOSETUP_BUILD_LUAC)
ADD_EXECUTABLE(mojoluac ${MOJOLUAC_SRCS})
TARGET_LINK_LIBRARIES(mojoluac ${OPTIONAL_LIBS})
GET_TARGET_PROPERTY(MOJOLUAC_LOCATION mojoluac LOCATION)
# !!! FIXME: actually compile this.
ADD_CUSTOM_TARGET(lua "${MOJOLUAC_LOCATION}" -p ${CMAKE_CURRENT_SOURCE_DIR}/scripts/*.lua)
ENDIF(MOJOSETUP_BUILD_LUAC)
ADD_EXECUTABLE(mojosetup ${USES_WINMAIN} ${MOJOSETUP_SRCS} ${OPTIONAL_SRCS})
GET_TARGET_PROPERTY(MOJOSETUP_BINARY_LOCATION mojosetup LOCATION)
TARGET_LINK_LIBRARIES(mojosetup ${OPTIONAL_LIBS})
SET(MOJOSETUP_TARGETS "${MOJOSETUP_TARGETS};mojosetup")
ADD_EXECUTABLE(make_self_extracting misc/make_self_extracting.c)
# For cobbling together a skeleton installer...
# !!! FIXME: all of these custom .cmake files are built-in commands in CMake 2.6.(4?) ...!
ADD_CUSTOM_TARGET(skeleton
COMMENT "Assembling Skeleton..."
COMMAND ${CMAKE_COMMAND} -DDIR=${CMAKE_BINARY_DIR}/skeleton -P ${CMAKE_SOURCE_DIR}/misc/rm_recurse.cmake
COMMAND ${CMAKE_COMMAND} -DDIR=${CMAKE_BINARY_DIR}/skeleton -P ${CMAKE_SOURCE_DIR}/misc/mkdir.cmake
COMMAND ${CMAKE_COMMAND} -DDIR=${CMAKE_BINARY_DIR}/skeleton/scripts -P ${CMAKE_SOURCE_DIR}/misc/mkdir.cmake
COMMAND ${CMAKE_COMMAND} -DDIR=${CMAKE_BINARY_DIR}/skeleton/guis -P ${CMAKE_SOURCE_DIR}/misc/mkdir.cmake
COMMAND ${CMAKE_COMMAND} -DDIR=${CMAKE_BINARY_DIR}/skeleton/data -P ${CMAKE_SOURCE_DIR}/misc/mkdir.cmake
COMMAND ${CMAKE_COMMAND} -DFROM=${CMAKE_SOURCE_DIR}/scripts/*.lua -DTO=${CMAKE_BINARY_DIR}/skeleton/scripts -P ${CMAKE_SOURCE_DIR}/misc/cp.cmake
COMMAND ${CMAKE_COMMAND} -DFROM=${CMAKE_SOURCE_DIR}/*mojosetupgui*.* -DTO=${CMAKE_BINARY_DIR}/skeleton/guis -P ${CMAKE_SOURCE_DIR}/misc/cp.cmake
COMMAND ${CMAKE_COMMAND} -DFROM=${MOJOSETUP_BINARY_LOCATION} -DTO=${CMAKE_BINARY_DIR}/skeleton -P ${CMAKE_SOURCE_DIR}/misc/cp.cmake
)
ADD_DEPENDENCIES(skeleton ${MOJOSETUP_TARGETS})
# end of CMakeLists.txt ...

View File

@@ -1,32 +0,0 @@
Copyright (c) 2006-2010 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>
(Please note that other pieces of code in MojoSetup fall under BSD-like and/or
public domain licenses: lua, libfetch, zlib, bzlib, liblzma, stb_image, etc.
All software statically linked to MojoSetup was explicitly chosen to be
friendly with closed-source software, in case the installer needs a
proprietary change. I am not a lawyer and this is not legal advice. Please
have a lawyer consider the licenses if you have any concerns.)

View File

@@ -1,295 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Steffen Pankratz.
*
Copyright (c) 2006-2010 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>
*
*/
#include "fileio.h"
#include "platform.h"
#if !SUPPORT_PCK
MojoArchive *MojoArchive_createPCK(MojoInput *io) { return NULL; }
#else
#define PCK_MAGIC 0x534c4850
typedef struct
{
uint32 Magic; // 4 bytes, has to be PCK_MAGIC (0x534c4850)
uint32 StartOfBinaryData; // 4 bytes, offset to the data
} PCKheader;
typedef struct
{
int8 filename[60]; // 60 bytes, null terminated
uint32 filesize; // 4 bytes
} PCKentry;
typedef struct
{
uint64 fileCount;
uint64 dataStart;
uint64 nextFileStart;
int64 nextEnumPos;
MojoArchiveEntry *archiveEntries;
} PCKinfo;
static boolean MojoInput_pck_ready(MojoInput *io)
{
return true; // !!! FIXME?
} // MojoInput_pck_ready
static int64 MojoInput_pck_read(MojoInput *io, void *buf, uint32 bufsize)
{
MojoArchive *ar = (MojoArchive *) io->opaque;
const MojoArchiveEntry *entry = &ar->prevEnum;
int64 pos = io->tell(io);
if ((pos + bufsize) > entry->filesize)
bufsize = (uint32) (entry->filesize - pos);
return ar->io->read(ar->io, buf, bufsize);
} // MojoInput_pck_read
static boolean MojoInput_pck_seek(MojoInput *io, uint64 pos)
{
MojoArchive *ar = (MojoArchive *) io->opaque;
const PCKinfo *info = (PCKinfo *) ar->opaque;
const MojoArchiveEntry *entry = &ar->prevEnum;
boolean retval = false;
if (pos < ((uint64) entry->filesize))
{
const uint64 newpos = (info->nextFileStart - entry->filesize) + pos;
retval = ar->io->seek(ar->io, newpos);
} // if
return retval;
} // MojoInput_pck_seek
static int64 MojoInput_pck_tell(MojoInput *io)
{
MojoArchive *ar = (MojoArchive *) io->opaque;
const PCKinfo *info = (PCKinfo *) ar->opaque;
const MojoArchiveEntry *entry = &ar->prevEnum;
return ar->io->tell(ar->io) - (info->nextFileStart - entry->filesize);
} // MojoInput_pck_tell
static int64 MojoInput_pck_length(MojoInput *io)
{
MojoArchive *ar = (MojoArchive *) io->opaque;
const MojoArchiveEntry *entry = &ar->prevEnum;
return entry->filesize;
} // MojoInput_pck_length
static MojoInput *MojoInput_pck_duplicate(MojoInput *io)
{
MojoInput *retval = NULL;
fatal(_("BUG: Can't duplicate pck inputs")); // !!! FIXME: why not?
return retval;
} // MojoInput_pck_duplicate
static void MojoInput_pck_close(MojoInput *io)
{
free(io);
} // MojoInput_pck_close
// MojoArchive implementation...
static boolean MojoArchive_pck_enumerate(MojoArchive *ar)
{
MojoArchiveEntry *archiveEntries = NULL;
PCKinfo *info = (PCKinfo *) ar->opaque;
const int dataStart = info->dataStart;
const int fileCount = dataStart / sizeof (PCKentry);
const size_t len = fileCount * sizeof (MojoArchiveEntry);
PCKentry fileEntry;
uint64 i, realFileCount = 0;
char directory[256] = {'\0'};
MojoInput *io = ar->io;
MojoArchive_resetEntry(&ar->prevEnum);
archiveEntries = (MojoArchiveEntry *) xmalloc(len);
for (i = 0; i < fileCount; i++)
{
int dotdot;
int64 br;
br = io->read(io, fileEntry.filename, sizeof (fileEntry.filename));
if (br != sizeof (fileEntry.filename))
return false;
else if (!MojoInput_readui32(io, &fileEntry.filesize))
return false;
dotdot = (strcmp(fileEntry.filename, "..") == 0);
if ((!dotdot) && (fileEntry.filesize == 0x80000000))
{
MojoArchiveEntry *entry = &archiveEntries[realFileCount];
strcat(directory, fileEntry.filename);
strcat(directory, "/");
entry->filename = xstrdup(directory);
entry->type = MOJOARCHIVE_ENTRY_DIR;
entry->perms = MojoPlatform_defaultDirPerms();
entry->filesize = 0;
realFileCount++;
} // if
else if ((dotdot) && (fileEntry.filesize == 0x80000000))
{
// remove trailing path separator
char *pathSep;
const size_t strLength = strlen(directory);
directory[strLength - 1] = '\0';
pathSep = strrchr(directory, '/');
if(pathSep != NULL)
{
pathSep++;
*pathSep = '\0';
} // if
} // else if
else
{
MojoArchiveEntry *entry = &archiveEntries[realFileCount];
if (directory[0] == '\0')
entry->filename = xstrdup(fileEntry.filename);
else
{
const size_t len = sizeof (char) * strlen(directory) +
strlen(fileEntry.filename) + 1;
entry->filename = (char *) xmalloc(len);
strcat(entry->filename, directory);
strcat(entry->filename, fileEntry.filename);
} // else
entry->perms = MojoPlatform_defaultFilePerms();
entry->type = MOJOARCHIVE_ENTRY_FILE;
entry->filesize = fileEntry.filesize;
realFileCount++;
} // else
} // for
info->fileCount = realFileCount;
info->archiveEntries = archiveEntries;
info->nextEnumPos = 0;
info->nextFileStart = dataStart;
return true;
} // MojoArchive_pck_enumerate
static const MojoArchiveEntry *MojoArchive_pck_enumNext(MojoArchive *ar)
{
PCKinfo *info = (PCKinfo *) ar->opaque;
const MojoArchiveEntry *entry = &info->archiveEntries[info->nextEnumPos];
if (info->nextEnumPos >= info->fileCount)
return NULL;
if (!ar->io->seek(ar->io, info->nextFileStart))
return NULL;
info->nextEnumPos++;
info->nextFileStart += entry->filesize;
memcpy(&ar->prevEnum, entry, sizeof (ar->prevEnum));
return &ar->prevEnum;
} // MojoArchive_pck_enumNext
static MojoInput *MojoArchive_pck_openCurrentEntry(MojoArchive *ar)
{
MojoInput *io = NULL;
io = (MojoInput *) xmalloc(sizeof (MojoInput));
io->ready = MojoInput_pck_ready;
io->read = MojoInput_pck_read;
io->seek = MojoInput_pck_seek;
io->tell = MojoInput_pck_tell;
io->length = MojoInput_pck_length;
io->duplicate = MojoInput_pck_duplicate;
io->close = MojoInput_pck_close;
io->opaque = ar;
return io;
} // MojoArchive_pck_openCurrentEntry
static void MojoArchive_pck_close(MojoArchive *ar)
{
int i;
PCKinfo *info = (PCKinfo *) ar->opaque;
ar->io->close(ar->io);
for (i = 0; i < info->fileCount; i++)
{
MojoArchiveEntry *entry = &info->archiveEntries[i];
free(entry->filename);
} // for
free(info->archiveEntries);
free(info);
free(ar);
} // MojoArchive_pck_close
MojoArchive *MojoArchive_createPCK(MojoInput *io)
{
MojoArchive *ar = NULL;
PCKinfo *pckInfo = NULL;
PCKheader pckHeader;
if (!MojoInput_readui32(io, &pckHeader.Magic))
return NULL;
else if (!MojoInput_readui32(io, &pckHeader.StartOfBinaryData))
return NULL;
// Check if this is a *.pck file.
if (pckHeader.Magic != PCK_MAGIC)
return NULL;
pckInfo = (PCKinfo *) xmalloc(sizeof (PCKinfo));
pckInfo->dataStart = pckHeader.StartOfBinaryData + sizeof (PCKheader);
ar = (MojoArchive *) xmalloc(sizeof (MojoArchive));
ar->opaque = pckInfo;
ar->enumerate = MojoArchive_pck_enumerate;
ar->enumNext = MojoArchive_pck_enumNext;
ar->openCurrentEntry = MojoArchive_pck_openCurrentEntry;
ar->close = MojoArchive_pck_close;
ar->io = io;
return ar;
} // MojoArchive_createPCK
#endif // SUPPORT_PCK
// end of archive_pck.c ...

View File

@@ -1,250 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Steffen Pankratz.
*
Copyright (c) 2006-2010 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>
*
*/
#include "fileio.h"
#include "platform.h"
#if !SUPPORT_PKG
MojoArchive *MojoArchive_createPKG(MojoInput *io) { return NULL; }
#else
#define PKG_MAGIC 0x4f504b47
typedef struct
{
uint32 magic; // 4 bytes, has to be PKG_MAGIC (0x4f504b47)
uint32 fileCount; // 4 bytes, number of files in the archive
} PKGheader;
typedef struct
{
uint64 nextFileStart;
} PKGinfo;
static boolean MojoInput_pkg_ready(MojoInput *io)
{
return true;
} // MojoInput_pkg_ready
static int64 MojoInput_pkg_read(MojoInput *io, void *buf, uint32 bufsize)
{
MojoArchive *ar = (MojoArchive *) io->opaque;
const MojoArchiveEntry *entry = &ar->prevEnum;
int64 pos = io->tell(io);
if ((pos + bufsize) > entry->filesize)
bufsize = (uint32) (entry->filesize - pos);
return ar->io->read(ar->io, buf, bufsize);
} // MojoInput_pkg_read
static boolean MojoInput_pkg_seek(MojoInput *io, uint64 pos)
{
MojoArchive *ar = (MojoArchive *) io->opaque;
const PKGinfo *info = (PKGinfo *) ar->opaque;
const MojoArchiveEntry *entry = &ar->prevEnum;
boolean retval = false;
if (pos < ((uint64) entry->filesize))
{
const uint64 newpos = (info->nextFileStart - entry->filesize) + pos;
retval = ar->io->seek(ar->io, newpos);
} // if
return retval;
} // MojoInput_pkg_seek
static int64 MojoInput_pkg_tell(MojoInput *io)
{
MojoArchive *ar = (MojoArchive *) io->opaque;
const PKGinfo *info = (PKGinfo *) ar->opaque;
const MojoArchiveEntry *entry = &ar->prevEnum;
return ar->io->tell(ar->io) - (info->nextFileStart - entry->filesize);
} // MojoInput_pkg_tell
static int64 MojoInput_pkg_length(MojoInput *io)
{
MojoArchive *ar = (MojoArchive *) io->opaque;
const MojoArchiveEntry *entry = &ar->prevEnum;
return entry->filesize;
} // MojoInput_pkg_length
static MojoInput *MojoInput_pkg_duplicate(MojoInput *io)
{
MojoInput *retval = NULL;
fatal(_("BUG: Can't duplicate pkg inputs")); // !!! FIXME: why not?
return retval;
} // MojoInput_pkg_duplicate
static void MojoInput_pkg_close(MojoInput *io)
{
free(io);
} // MojoInput_pkg_close
// MojoArchive implementation...
static boolean MojoArchive_pkg_enumerate(MojoArchive *ar)
{
PKGinfo *info = (PKGinfo *) ar->opaque;
MojoArchive_resetEntry(&ar->prevEnum);
info->nextFileStart = sizeof (PKGheader);
return true;
} // MojoArchive_pkg_enumerate
static const MojoArchiveEntry *MojoArchive_pkg_enumNext(MojoArchive *ar)
{
PKGinfo *info = (PKGinfo *) ar->opaque;
MojoInput *io = ar->io;
int64 ret = 0;
uint32 pathNameLength = 0;
uint64 pathNameStart = 0;
uint32 fileNameLength = 0;
uint64 fileNameStart = 0;
uint32 fileSize = 0;
char* backSlash = NULL;
if (!ar->io->seek(ar->io, info->nextFileStart))
return NULL;
// read the path name length
if (!MojoInput_readui32(io, &pathNameLength))
return NULL;
pathNameStart = ar->io->tell(ar->io);
// skip reading the path name for now
if (!ar->io->seek(ar->io, pathNameStart + pathNameLength))
return NULL;
// read the file name length
if (!MojoInput_readui32(io, &fileNameLength))
return NULL;
fileNameStart = ar->io->tell(ar->io);
// as both strings are null terminated, we need one byte less
ar->prevEnum.filename = (char *) xmalloc(pathNameLength + fileNameLength -1);
// go to the start of the path name
if (!ar->io->seek(ar->io, pathNameStart))
return NULL;
// read the path name
ret = io->read(io, ar->prevEnum.filename, pathNameLength);
if (ret != pathNameLength)
return false;
// replace backslashes with slashes in the path name
while((backSlash = strchr(ar->prevEnum.filename, '\\')))
*backSlash = '/';
// go the start of the file name
if (!ar->io->seek(ar->io, fileNameStart))
return NULL;
// read the file name
ret = io->read(io, ar->prevEnum.filename + pathNameLength - 1, fileNameLength);
if (ret != fileNameLength)
return false;
// read the file size
if (!MojoInput_readui32(io, &fileSize))
return NULL;
// skip the next 8 bytes, probably some kind of check sum
if (!ar->io->seek(ar->io, ar->io->tell(ar->io) + 8))
return NULL;
ar->prevEnum.filesize = fileSize;
ar->prevEnum.perms = MojoPlatform_defaultFilePerms();
ar->prevEnum.type = MOJOARCHIVE_ENTRY_FILE;
info->nextFileStart = ar->io->tell(ar->io) + ar->prevEnum.filesize;
return &ar->prevEnum;
} // MojoArchive_pkg_enumNext
static MojoInput *MojoArchive_pkg_openCurrentEntry(MojoArchive *ar)
{
MojoInput *io = NULL;
io = (MojoInput *) xmalloc(sizeof (MojoInput));
io->ready = MojoInput_pkg_ready;
io->read = MojoInput_pkg_read;
io->seek = MojoInput_pkg_seek;
io->tell = MojoInput_pkg_tell;
io->length = MojoInput_pkg_length;
io->duplicate = MojoInput_pkg_duplicate;
io->close = MojoInput_pkg_close;
io->opaque = ar;
return io;
} // MojoArchive_pkg_openCurrentEntry
static void MojoArchive_pkg_close(MojoArchive *ar)
{
PKGinfo *info = (PKGinfo *) ar->opaque;
ar->io->close(ar->io);
free(info);
free(ar);
} // MojoArchive_pkg_close
MojoArchive *MojoArchive_createPKG(MojoInput *io)
{
MojoArchive *ar = NULL;
PKGinfo *pkgInfo = NULL;
PKGheader pkgHeader;
if (!MojoInput_readui32(io, &pkgHeader.magic))
return NULL;
else if (!MojoInput_readui32(io, &pkgHeader.fileCount))
return NULL;
// Check if this is a *.pkg file.
if (pkgHeader.magic != PKG_MAGIC)
return NULL;
pkgInfo = (PKGinfo *) xmalloc(sizeof (PKGinfo));
ar = (MojoArchive *) xmalloc(sizeof (MojoArchive));
ar->opaque = pkgInfo;
ar->enumerate = MojoArchive_pkg_enumerate;
ar->enumNext = MojoArchive_pkg_enumNext;
ar->openCurrentEntry = MojoArchive_pkg_openCurrentEntry;
ar->close = MojoArchive_pkg_close;
ar->io = io;
return ar;
} // MojoArchive_createPKG
#endif // SUPPORT_PKG
// end of archive_pkg.c ...

View File

@@ -1,372 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*
*/
// Specs for the tar format can be found here...
// http://www.gnu.org/software/tar/manual/html_section/Standard.html
#include "fileio.h"
#if !SUPPORT_TAR
MojoArchive *MojoArchive_createTAR(MojoInput *io) { return NULL; }
#else
// MojoInput implementation...
// Decompression is handled in the parent MojoInput, so this just needs to
// make sure we stay within the bounds of the tarfile entry.
typedef struct TARinput
{
int64 fsize;
int64 offset;
MojoArchive *ar;
} TARinput;
typedef struct TARinfo
{
MojoInput *input;
uint64 curFileStart;
uint64 nextEnumPos;
} TARinfo;
static boolean MojoInput_tar_ready(MojoInput *io)
{
return true; // !!! FIXME: ready if there are bytes uncompressed.
} // MojoInput_tar_ready
static int64 MojoInput_tar_read(MojoInput *io, void *buf, uint32 bufsize)
{
TARinput *input = (TARinput *) io->opaque;
int64 pos = io->tell(io);
if ((pos + bufsize) > input->fsize)
bufsize = (uint32) (input->fsize - pos);
return input->ar->io->read(input->ar->io, buf, bufsize);
} // MojoInput_tar_read
static boolean MojoInput_tar_seek(MojoInput *io, uint64 pos)
{
TARinput *input = (TARinput *) io->opaque;
boolean retval = false;
if (pos < ((uint64) input->fsize))
retval = input->ar->io->seek(input->ar->io, input->offset + pos);
return retval;
} // MojoInput_tar_seek
static int64 MojoInput_tar_tell(MojoInput *io)
{
TARinput *input = (TARinput *) io->opaque;
return input->ar->io->tell(input->ar->io) - input->offset;
} // MojoInput_tar_tell
static int64 MojoInput_tar_length(MojoInput *io)
{
return ((TARinput *) io->opaque)->fsize;
} // MojoInput_tar_length
static MojoInput *MojoInput_tar_duplicate(MojoInput *io)
{
MojoInput *retval = NULL;
fatal(_("BUG: Can't duplicate tar inputs")); // !!! FIXME: why not?
#if 0
TARinput *input = (TARinput *) io->opaque;
MojoInput *origio = (MojoInput *) io->opaque;
MojoInput *newio = origio->duplicate(origio);
if (newio != NULL)
{
TARinput *newopaque = (TARinput *) xmalloc(sizeof (TARinput));
newopaque->origio = newio;
newopaque->fsize = input->fsize;
newopaque->offset = input->offset;
retval = (MojoInput *) xmalloc(sizeof (MojoInput));
memcpy(retval, io, sizeof (MojoInput));
retval->opaque = newopaque;
} // if
#endif
return retval;
} // MojoInput_tar_duplicate
static void MojoInput_tar_close(MojoInput *io)
{
TARinput *input = (TARinput *) io->opaque;
TARinfo *info = (TARinfo *) input->ar->opaque;
//input->ar->io->close(input->ar->io);
info->input = NULL;
free(input);
free(io);
} // MojoInput_tar_close
// MojoArchive implementation...
static boolean MojoArchive_tar_enumerate(MojoArchive *ar)
{
TARinfo *info = (TARinfo *) ar->opaque;
MojoArchive_resetEntry(&ar->prevEnum);
if (info->input != NULL)
fatal("BUG: tar entry still open on new enumeration");
info->curFileStart = info->nextEnumPos = 0;
return true;
} // MojoArchive_tar_enumerate
// These are byte offsets where fields start in the tar header blocks.
#define TAR_FNAME 0
#define TAR_FNAMELEN 100
#define TAR_MODE 100
#define TAR_MODELEN 8
#define TAR_UID 108
#define TAR_UIDLEN 8
#define TAR_GID 116
#define TAR_GIDLEN 8
#define TAR_SIZE 124
#define TAR_SIZELEN 12
#define TAR_MTIME 136
#define TAR_MTIMELEN 12
#define TAR_CHKSUM 148
#define TAR_CHKSUMLEN 8
#define TAR_TYPE 156
#define TAR_TYPELEN 1
#define TAR_LINKNAME 157
#define TAR_LINKNAMELEN 100
#define TAR_MAGIC 257
#define TAR_MAGICLEN 6
#define TAR_VERSION 263
#define TAR_VERSIONLEN 2
#define TAR_UNAME 265
#define TAR_UNAMELEN 32
#define TAR_GNAME 297
#define TAR_GNAMELEN 32
#define TAR_DEVMAJOR 329
#define TAR_DEVMAJORLEN 8
#define TAR_DEVMINOR 337
#define TAR_DEVMINORLEN 8
#define TAR_FNAMEPRE 345
#define TAR_FNAMEPRELEN 155
// tar entry types...
#define TAR_TYPE_FILE '0'
#define TAR_TYPE_HARDLINK '1'
#define TAR_TYPE_SYMLINK '2'
#define TAR_TYPE_CHARDEV '3'
#define TAR_TYPE_BLOCKDEV '4'
#define TAR_TYPE_DIRECTORY '5'
#define TAR_TYPE_FIFO '6'
static boolean is_ustar(const uint8 *block)
{
return ( (memcmp(&block[TAR_MAGIC], "ustar ", TAR_MAGICLEN) == 0) ||
(memcmp(&block[TAR_MAGIC], "ustar\0", TAR_MAGICLEN) == 0) );
} // is_ustar
static int64 octal_convert(const uint8 *str, const size_t len)
{
int64 retval = 0;
int64 multiplier = 1;
const uint8 *end = str + len;
const uint8 *ptr;
while ((*str == ' ') && (str != end))
str++;
ptr = str;
while ((ptr != end) && (*ptr >= '0') && (*ptr <= '7'))
ptr++;
while (--ptr >= str)
{
uint64 val = *ptr - '0';
retval += val * multiplier;
multiplier *= 8;
} // while
return retval;
} // octal_convert
static const MojoArchiveEntry *MojoArchive_tar_enumNext(MojoArchive *ar)
{
TARinfo *info = (TARinfo *) ar->opaque;
boolean zeroes = true;
boolean ustar = false;
uint8 scratch[512];
uint8 block[512];
size_t fnamelen = 0;
int type = 0;
memset(scratch, '\0', sizeof (scratch));
MojoArchive_resetEntry(&ar->prevEnum);
if (info->input != NULL)
fatal("BUG: tar entry still open on new enumeration");
if (!ar->io->seek(ar->io, info->nextEnumPos))
return NULL;
// Find a non-zero block of data. Tarballs have two 512 blocks filled with
// null bytes at the end of the archive, but you can cat tarballs
// together, so you can't treat them as EOF indicators. Just skip them.
while (zeroes)
{
if (ar->io->read(ar->io, block, sizeof (block)) != sizeof (block))
return NULL; // !!! FIXME: fatal() ?
zeroes = (memcmp(block, scratch, sizeof (block)) == 0);
} // while
// !!! FIXME We should probably check the checksum.
ustar = is_ustar(block);
ar->prevEnum.perms = (uint16) octal_convert(&block[TAR_MODE], TAR_MODELEN);
ar->prevEnum.filesize = octal_convert(&block[TAR_SIZE], TAR_SIZELEN);
info->curFileStart = info->nextEnumPos + 512;
info->nextEnumPos += 512 + ar->prevEnum.filesize;
if (ar->prevEnum.filesize % 512)
info->nextEnumPos += 512 - (ar->prevEnum.filesize % 512);
// We count on (scratch) being zeroed out here!
// prefix of filename is at the end for legacy compat.
if (ustar)
memcpy(scratch, &block[TAR_FNAMEPRE], TAR_FNAMEPRELEN);
fnamelen = strlen((const char *) scratch);
memcpy(&scratch[fnamelen], &block[TAR_FNAME], TAR_FNAMELEN);
fnamelen += strlen((const char *) &scratch[fnamelen]);
if (fnamelen == 0)
return NULL; // corrupt file. !!! FIXME: fatal() ?
ar->prevEnum.filename = xstrdup((const char *) scratch);
type = block[TAR_TYPE];
if (type == 0) // some archivers do the file type as 0 instead of '0'.
type = TAR_TYPE_FILE;
if (ar->prevEnum.filename[fnamelen-1] == '/')
{
while (ar->prevEnum.filename[fnamelen-1] == '/')
ar->prevEnum.filename[--fnamelen] = '\0';
// legacy tar entries don't have a dir type, they just append a '/' to
// the filename...
if ((!ustar) && (type == TAR_TYPE_FILE))
type = TAR_TYPE_DIRECTORY;
} // if
ar->prevEnum.type = MOJOARCHIVE_ENTRY_UNKNOWN;
if (type == TAR_TYPE_FILE)
ar->prevEnum.type = MOJOARCHIVE_ENTRY_FILE;
else if (type == TAR_TYPE_DIRECTORY)
ar->prevEnum.type = MOJOARCHIVE_ENTRY_DIR;
else if (type == TAR_TYPE_SYMLINK)
{
ar->prevEnum.type = MOJOARCHIVE_ENTRY_SYMLINK;
memcpy(scratch, &block[TAR_LINKNAME], TAR_LINKNAMELEN);
scratch[TAR_LINKNAMELEN] = '\0'; // just in case.
ar->prevEnum.linkdest = xstrdup((const char *) scratch);
} // else if
return &ar->prevEnum;
} // MojoArchive_tar_enumNext
static MojoInput *MojoArchive_tar_openCurrentEntry(MojoArchive *ar)
{
TARinfo *info = (TARinfo *) ar->opaque;
MojoInput *io = NULL;
TARinput *opaque = NULL;
if (info->curFileStart == 0)
return NULL;
// Can't open multiple, since we would end up decompressing twice
// to enumerate the next file, so I imposed this limitation for now.
if (info->input != NULL)
fatal("BUG: tar entry double open");
// !!! FIXME: replace this with MojoInput_newFromSubset()?
opaque = (TARinput *) xmalloc(sizeof (TARinput));
opaque->ar = ar;
opaque->fsize = ar->prevEnum.filesize;
opaque->offset = info->curFileStart;
io = (MojoInput *) xmalloc(sizeof (MojoInput));
io->ready = MojoInput_tar_ready;
io->read = MojoInput_tar_read;
io->seek = MojoInput_tar_seek;
io->tell = MojoInput_tar_tell;
io->length = MojoInput_tar_length;
io->duplicate = MojoInput_tar_duplicate;
io->close = MojoInput_tar_close;
io->opaque = opaque;
info->input = io;
return io;
} // MojoArchive_tar_openCurrentEntry
static void MojoArchive_tar_close(MojoArchive *ar)
{
TARinfo *info = (TARinfo *) ar->opaque;
MojoArchive_resetEntry(&ar->prevEnum);
ar->io->close(ar->io);
free(info);
free(ar);
} // MojoArchive_tar_close
MojoArchive *MojoArchive_createTAR(MojoInput *io)
{
MojoArchive *ar = NULL;
uint8 sig[512];
const int64 br = io->read(io, sig, sizeof (sig));
// See if this is a tar archive. We only support "USTAR" format,
// since it has a detectable header. GNU and BSD tar has been creating
// these for years, so it's okay to ignore other ones, I guess.
if ((!io->seek(io, 0)) || (br != sizeof (sig)) || (!is_ustar(sig)) )
return NULL;
// okay, it's a tarball, we're good to go.
ar = (MojoArchive *) xmalloc(sizeof (MojoArchive));
ar->opaque = (TARinfo *) xmalloc(sizeof (TARinfo));
ar->enumerate = MojoArchive_tar_enumerate;
ar->enumNext = MojoArchive_tar_enumNext;
ar->openCurrentEntry = MojoArchive_tar_openCurrentEntry;
ar->close = MojoArchive_tar_close;
ar->io = io;
return ar;
} // MojoArchive_createTAR
#endif // SUPPORT_TAR
// end of archive_tar.c ...

View File

@@ -1,373 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*
*/
#include "fileio.h"
#include "platform.h"
#if !SUPPORT_UZ2
MojoArchive *MojoArchive_createUZ2(MojoInput *io) { return NULL; }
#else
// UZ2 format is a simple compressed file format used by UnrealEngine2.
// it's just a stream of blocks like this:
// uint32 compressed size
// uint32 uncompressed size
// uint8 data[compressed size] <-- unpacks to (uncompressed size) bytes.
// Decompression is handled by zlib's "uncompress" function.
#include "miniz.h"
#define MAXCOMPSIZE 32768
#define MAXUNCOMPSIZE 33096 // MAXCOMPSIZE + 1%
// MojoInput implementation...
// Decompression is handled in the parent MojoInput, so this just needs to
// make sure we stay within the bounds of the tarfile entry.
typedef struct UZ2input
{
MojoInput *io;
int64 fsize;
uint64 position;
uint32 compsize;
uint8 compbuf[MAXCOMPSIZE];
uint32 uncompsize;
uint8 uncompbuf[MAXUNCOMPSIZE];
uint32 uncompindex;
} UZ2input;
typedef struct UZ2info
{
char *outname;
int64 outsize;
boolean enumerated;
} UZ2info;
static boolean unpack(UZ2input *inp)
{
MojoInput *io = inp->io;
uLongf ul = (uLongf) inp->uncompsize;
// we checked these formally elsewhere.
assert(inp->compsize > 0);
assert(inp->uncompsize > 0);
assert(inp->compsize <= MAXCOMPSIZE);
assert(inp->uncompsize <= MAXUNCOMPSIZE);
if (io->read(io, inp->compbuf, inp->compsize) != inp->compsize)
return false;
if (uncompress(inp->uncompbuf, &ul, inp->compbuf, inp->compsize) != Z_OK)
return false;
if (ul != ((uLongf) inp->uncompsize)) // corrupt data.
return false;
inp->uncompindex = 0;
return true;
} // unpack
static boolean MojoInput_uz2_ready(MojoInput *io)
{
UZ2input *input = (UZ2input *) io->opaque;
if (input->uncompsize > 0)
return true;
return true; // !!! FIXME: need to know we have a full compressed block.
} // MojoInput_uz2_ready
static int64 MojoInput_uz2_read(MojoInput *io, void *_buf, uint32 bufsize)
{
uint8 *buf = (uint8 *) _buf;
UZ2input *input = (UZ2input *) io->opaque;
int64 retval = 0;
while (bufsize > 0)
{
const uint32 available = input->uncompsize - input->uncompindex;
const uint32 cpy = (available < bufsize) ? available : bufsize;
if (available == 0)
{
if (input->position == input->fsize)
return 0;
else if (!MojoInput_readui32(input->io, &input->compsize))
return (retval == 0) ? -1 : retval;
else if (!MojoInput_readui32(input->io, &input->uncompsize))
return (retval == 0) ? -1 : retval;
else if (!unpack(input))
return (retval == 0) ? -1 : retval;
continue; // try again.
} // if
memcpy(buf, input->uncompbuf + input->uncompindex, cpy);
buf += cpy;
bufsize -= cpy;
retval += cpy;
input->uncompindex += cpy;
input->position += cpy;
} // while
return retval;
} // MojoInput_uz2_read
static boolean MojoInput_uz2_seek(MojoInput *io, uint64 pos)
{
UZ2input *input = (UZ2input *) io->opaque;
int64 seekpos = 0;
// in a perfect world, this wouldn't seek from the start if moving
// forward. But oh well.
input->position = 0;
while (input->position < pos)
{
if (!input->io->seek(input->io, seekpos))
return false;
else if (!MojoInput_readui32(io, &input->compsize))
return false;
else if (!MojoInput_readui32(io, &input->uncompsize))
return false;
// we checked these formally elsewhere.
assert(input->compsize > 0);
assert(input->uncompsize > 0);
assert(input->compsize <= MAXCOMPSIZE);
assert(input->uncompsize <= MAXUNCOMPSIZE);
input->position += input->uncompsize;
seekpos += (sizeof (uint32) * 2) + input->compsize;
} // while
// we are positioned on the compressed block that contains the seek target.
if (!unpack(input))
return false;
input->position -= input->uncompsize;
input->uncompindex = (uint32) (pos - input->position);
input->position += input->uncompindex;
return true;
} // MojoInput_uz2_seek
static int64 MojoInput_uz2_tell(MojoInput *io)
{
return (int64) (((UZ2input *) io->opaque)->position);
} // MojoInput_uz2_tell
static int64 MojoInput_uz2_length(MojoInput *io)
{
return ((UZ2input *) io->opaque)->fsize;
} // MojoInput_uz2_length
static MojoInput *MojoInput_uz2_duplicate(MojoInput *io)
{
MojoInput *retval = NULL;
UZ2input *input = (UZ2input *) io->opaque;
MojoInput *newio = input->io->duplicate(input->io);
if (newio != NULL)
{
UZ2input *newopaque = (UZ2input *) xmalloc(sizeof (UZ2input));
newopaque->io = newio;
newopaque->fsize = input->fsize;
// everything else is properly zero'd by xmalloc().
retval = (MojoInput *) xmalloc(sizeof (MojoInput));
memcpy(retval, io, sizeof (MojoInput));
retval->opaque = newopaque;
} // if
return retval;
} // MojoInput_uz2_duplicate
static void MojoInput_uz2_close(MojoInput *io)
{
UZ2input *input = (UZ2input *) io->opaque;
input->io->close(input->io);
free(input);
free(io);
} // MojoInput_uz2_close
// MojoArchive implementation...
static boolean MojoArchive_uz2_enumerate(MojoArchive *ar)
{
UZ2info *info = (UZ2info *) ar->opaque;
MojoArchive_resetEntry(&ar->prevEnum);
info->enumerated = false;
return true;
} // MojoArchive_uz2_enumerate
static const MojoArchiveEntry *MojoArchive_uz2_enumNext(MojoArchive *ar)
{
UZ2info *info = (UZ2info *) ar->opaque;
MojoArchive_resetEntry(&ar->prevEnum);
if (info->enumerated)
return NULL; // only one file in this "archive".
ar->prevEnum.perms = MojoPlatform_defaultFilePerms();
ar->prevEnum.filesize = info->outsize;
ar->prevEnum.filename = xstrdup(info->outname);
ar->prevEnum.type = MOJOARCHIVE_ENTRY_FILE;
info->enumerated = true;
return &ar->prevEnum;
} // MojoArchive_uz2_enumNext
static MojoInput *MojoArchive_uz2_openCurrentEntry(MojoArchive *ar)
{
UZ2info *info = (UZ2info *) ar->opaque;
MojoInput *io = NULL;
UZ2input *opaque = NULL;
MojoInput *dupio = NULL;
if (!info->enumerated)
return NULL;
dupio = ar->io->duplicate(ar->io);
if (dupio == NULL)
return NULL;
opaque = (UZ2input *) xmalloc(sizeof (UZ2input));
opaque->io = dupio;
opaque->fsize = info->outsize;
// rest is zero'd by xmalloc().
io = (MojoInput *) xmalloc(sizeof (MojoInput));
io->ready = MojoInput_uz2_ready;
io->read = MojoInput_uz2_read;
io->seek = MojoInput_uz2_seek;
io->tell = MojoInput_uz2_tell;
io->length = MojoInput_uz2_length;
io->duplicate = MojoInput_uz2_duplicate;
io->close = MojoInput_uz2_close;
io->opaque = opaque;
return io;
} // MojoArchive_uz2_openCurrentEntry
static void MojoArchive_uz2_close(MojoArchive *ar)
{
UZ2info *info = (UZ2info *) ar->opaque;
MojoArchive_resetEntry(&ar->prevEnum);
ar->io->close(ar->io);
free(info->outname);
free(info);
free(ar);
} // MojoArchive_uz2_close
// Unfortunately, we have to walk the whole file, but we don't have to actually
// do any decompression work here. Just seek, read 8 bytes, repeat until EOF.
static int64 calculate_uz2_outsize(MojoInput *io)
{
int64 retval = 0;
uint32 compsize = 0;
uint32 uncompsize = 0;
int64 pos = 0;
if (!io->seek(io, 0))
return -1;
while (MojoInput_readui32(io, &compsize))
{
if (!MojoInput_readui32(io, &uncompsize))
return -1;
else if ((compsize > MAXCOMPSIZE) || (uncompsize > MAXUNCOMPSIZE))
return -1;
else if ((compsize == 0) || (uncompsize == 0))
return -1;
retval += uncompsize;
pos += (sizeof (uint32) * 2) + compsize;
if (!io->seek(io, pos))
return -1;
} // while
if (!io->seek(io, 0)) // make sure we're back to the start.
return -1;
return retval;
} // calculate_uz2_outsize
MojoArchive *MojoArchive_createUZ2(MojoInput *io, const char *origfname)
{
MojoArchive *ar = NULL;
const char *fname = NULL;
char *outname = NULL;
size_t len = 0;
int64 outsize = 0;
UZ2info *uz2info = NULL;
// There's no magic in a UZ2 that allows us to identify the format.
// The higher-level won't call this unless the file extension in
// (origfname) is ".uz2"
// Figure out the output name ("x.uz2" would produce "x").
if (origfname == NULL)
return NULL; // just in case.
fname = strrchr(origfname, '/');
if (fname == NULL)
fname = origfname;
else
fname++;
len = strlen(fname) - 4; // -4 == ".uz2"
if (strcasecmp(fname + len, ".uz2") != 0)
return NULL; // just in case.
outsize = calculate_uz2_outsize(io);
if (outsize < 0)
return NULL; // wasn't really a uz2? Corrupt/truncated file?
outname = (char *) xmalloc(len+1);
memcpy(outname, fname, len);
outname[len] = '\0';
uz2info = (UZ2info *) xmalloc(sizeof (UZ2info));
uz2info->enumerated = false;
uz2info->outname = outname;
uz2info->outsize = outsize;
ar = (MojoArchive *) xmalloc(sizeof (MojoArchive));
ar->opaque = uz2info;
ar->enumerate = MojoArchive_uz2_enumerate;
ar->enumNext = MojoArchive_uz2_enumNext;
ar->openCurrentEntry = MojoArchive_uz2_openCurrentEntry;
ar->close = MojoArchive_uz2_close;
ar->io = io;
return ar;
} // MojoArchive_createUZ2
#endif // SUPPORT_UZ2
// end of archive_uz2.c ...

File diff suppressed because it is too large Load Diff

View File

@@ -1,97 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*
*/
/*
* This is in a separate file so that we can recompile it every time
* without it forcing a recompile on something ccache would otherwise not
* have to rebuild...this file's checksum changes every time you build it
* due to the __DATE__ and __TIME__ macros.
*
* The makefile will rebuild this file everytime it relinks an executable
* so that we'll always have a unique build string.
*
* APPNAME and APPREV need to be predefined in the build system.
* The rest are supposed to be supplied by the compiler.
*/
#ifndef APPID
#error Please define APPID in the build system.
#endif
#ifndef APPREV
#error Please define APPREV in the build system.
#endif
#if (defined __GNUC__)
# define VERSTR2(x) #x
# define VERSTR(x) VERSTR2(x)
# define COMPILERVER " " VERSTR(__GNUC__) "." VERSTR(__GNUC_MINOR__) "." VERSTR(__GNUC_PATCHLEVEL__)
#elif (defined __SUNPRO_C)
# define VERSTR2(x) #x
# define VERSTR(x) VERSTR2(x)
# define COMPILERVER " " VERSTR(__SUNPRO_C)
#elif (defined __VERSION__)
# define COMPILERVER " " __VERSION__
#else
# define COMPILERVER ""
#endif
#ifndef __DATE__
#define __DATE__ "(Unknown build date)"
#endif
#ifndef __TIME__
#define __TIME__ "(Unknown build time)"
#endif
#ifndef COMPILER
#if (defined __GNUC__)
#define COMPILER "GCC"
#elif (defined _MSC_VER)
#define COMPILER "Visual Studio"
#elif (defined __SUNPRO_C)
#define COMPILER "Sun Studio"
#else
#error Please define your platform.
#endif
#endif
// macro mess so we can turn APPID and APPREV into a string literal...
#define MAKEBUILDVERSTRINGLITERAL2(id, rev) \
#id ", revision " #rev ", built " __DATE__ " " __TIME__ \
", by " COMPILER COMPILERVER
#define MAKEBUILDVERSTRINGLITERAL(id, rev) MAKEBUILDVERSTRINGLITERAL2(id, rev)
const char *GBuildVer = MAKEBUILDVERSTRINGLITERAL(APPID, APPREV);
// end of buildver.c ...

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,282 +0,0 @@
/*-------------------------------------------------------------*/
/*--- Public header file for the library. ---*/
/*--- bzlib.h ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#ifndef _BZLIB_H
#define _BZLIB_H
#ifdef __cplusplus
extern "C" {
#endif
#define BZ_RUN 0
#define BZ_FLUSH 1
#define BZ_FINISH 2
#define BZ_OK 0
#define BZ_RUN_OK 1
#define BZ_FLUSH_OK 2
#define BZ_FINISH_OK 3
#define BZ_STREAM_END 4
#define BZ_SEQUENCE_ERROR (-1)
#define BZ_PARAM_ERROR (-2)
#define BZ_MEM_ERROR (-3)
#define BZ_DATA_ERROR (-4)
#define BZ_DATA_ERROR_MAGIC (-5)
#define BZ_IO_ERROR (-6)
#define BZ_UNEXPECTED_EOF (-7)
#define BZ_OUTBUFF_FULL (-8)
#define BZ_CONFIG_ERROR (-9)
typedef
struct {
char *next_in;
unsigned int avail_in;
unsigned int total_in_lo32;
unsigned int total_in_hi32;
char *next_out;
unsigned int avail_out;
unsigned int total_out_lo32;
unsigned int total_out_hi32;
void *state;
void *(*bzalloc)(void *,int,int);
void (*bzfree)(void *,void *);
void *opaque;
}
bz_stream;
#ifndef BZ_IMPORT
#define BZ_EXPORT
#endif
#ifndef BZ_NO_STDIO
/* Need a definitition for FILE */
#include <stdio.h>
#endif
#ifdef _WIN32
# include <windows.h>
# ifdef small
/* windows.h define small to char */
# undef small
# endif
# ifdef BZ_EXPORT
# define BZ_API(func) WINAPI func
# define BZ_EXTERN extern
# else
/* import windows dll dynamically */
# define BZ_API(func) (WINAPI * func)
# define BZ_EXTERN
# endif
#else
# define BZ_API(func) func
# define BZ_EXTERN extern
#endif
/*-- Core (low-level) library functions --*/
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
bz_stream* strm,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
bz_stream* strm,
int action
);
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
bz_stream *strm,
int verbosity,
int small
);
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
bz_stream *strm
);
/*-- High(er) level library functions --*/
#ifndef BZ_NO_STDIO
#define BZ_MAX_UNUSED 5000
typedef void BZFILE;
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
int* bzerror,
FILE* f,
int verbosity,
int small,
void* unused,
int nUnused
);
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
int* bzerror,
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
int* bzerror,
BZFILE* b,
void** unused,
int* nUnused
);
BZ_EXTERN int BZ_API(BZ2_bzRead) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
int* bzerror,
FILE* f,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in,
unsigned int* nbytes_out
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in_lo32,
unsigned int* nbytes_in_hi32,
unsigned int* nbytes_out_lo32,
unsigned int* nbytes_out_hi32
);
#endif
/*-- Utility functions --*/
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int small,
int verbosity
);
/*--
Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
to support better zlib compatibility.
This code is not _officially_ part of libbzip2 (yet);
I haven't tested it, documented it, or considered the
threading-safeness of it.
If this code breaks, please contact both Yoshioka and me.
--*/
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
void
);
#ifndef BZ_NO_STDIO
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
const char *path,
const char *mode
);
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
int fd,
const char *mode
);
BZ_EXTERN int BZ_API(BZ2_bzread) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzflush) (
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzclose) (
BZFILE* b
);
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
BZFILE *b,
int *errnum
);
#endif
#ifdef __cplusplus
}
#endif
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib.h ---*/
/*-------------------------------------------------------------*/

View File

@@ -1,509 +0,0 @@
/*-------------------------------------------------------------*/
/*--- Private header file for the library. ---*/
/*--- bzlib_private.h ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#ifndef _BZLIB_PRIVATE_H
#define _BZLIB_PRIVATE_H
#include <stdlib.h>
#ifndef BZ_NO_STDIO
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#endif
#include "bzlib.h"
/*-- General stuff. --*/
#define BZ_VERSION "1.0.6, 6-Sept-2010"
typedef char Char;
typedef unsigned char Bool;
typedef unsigned char UChar;
typedef int Int32;
typedef unsigned int UInt32;
typedef short Int16;
typedef unsigned short UInt16;
#define True ((Bool)1)
#define False ((Bool)0)
#ifndef __GNUC__
#define __inline__ /* */
#endif
#ifndef BZ_NO_STDIO
extern void BZ2_bz__AssertH__fail ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
#if BZ_DEBUG
#define AssertD(cond,msg) \
{ if (!(cond)) { \
fprintf ( stderr, \
"\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
exit(1); \
}}
#else
#define AssertD(cond,msg) /* */
#endif
#define VPrintf0(zf) \
fprintf(stderr,zf)
#define VPrintf1(zf,za1) \
fprintf(stderr,zf,za1)
#define VPrintf2(zf,za1,za2) \
fprintf(stderr,zf,za1,za2)
#define VPrintf3(zf,za1,za2,za3) \
fprintf(stderr,zf,za1,za2,za3)
#define VPrintf4(zf,za1,za2,za3,za4) \
fprintf(stderr,zf,za1,za2,za3,za4)
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
fprintf(stderr,zf,za1,za2,za3,za4,za5)
#else
extern void bz_internal_error ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) bz_internal_error ( errcode ); }
#define AssertD(cond,msg) do { } while (0)
#define VPrintf0(zf) do { } while (0)
#define VPrintf1(zf,za1) do { } while (0)
#define VPrintf2(zf,za1,za2) do { } while (0)
#define VPrintf3(zf,za1,za2,za3) do { } while (0)
#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
#endif
#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
/*-- Header bytes. --*/
#define BZ_HDR_B 0x42 /* 'B' */
#define BZ_HDR_Z 0x5a /* 'Z' */
#define BZ_HDR_h 0x68 /* 'h' */
#define BZ_HDR_0 0x30 /* '0' */
/*-- Constants for the back end. --*/
#define BZ_MAX_ALPHA_SIZE 258
#define BZ_MAX_CODE_LEN 23
#define BZ_RUNA 0
#define BZ_RUNB 1
#define BZ_N_GROUPS 6
#define BZ_G_SIZE 50
#define BZ_N_ITERS 4
#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
/*-- Stuff for randomising repetitive blocks. --*/
extern Int32 BZ2_rNums[512];
#define BZ_RAND_DECLS \
Int32 rNToGo; \
Int32 rTPos \
#define BZ_RAND_INIT_MASK \
s->rNToGo = 0; \
s->rTPos = 0 \
#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
#define BZ_RAND_UPD_MASK \
if (s->rNToGo == 0) { \
s->rNToGo = BZ2_rNums[s->rTPos]; \
s->rTPos++; \
if (s->rTPos == 512) s->rTPos = 0; \
} \
s->rNToGo--;
/*-- Stuff for doing CRCs. --*/
extern UInt32 BZ2_crc32Table[256];
#define BZ_INITIALISE_CRC(crcVar) \
{ \
crcVar = 0xffffffffL; \
}
#define BZ_FINALISE_CRC(crcVar) \
{ \
crcVar = ~(crcVar); \
}
#define BZ_UPDATE_CRC(crcVar,cha) \
{ \
crcVar = (crcVar << 8) ^ \
BZ2_crc32Table[(crcVar >> 24) ^ \
((UChar)cha)]; \
}
/*-- States and modes for compression. --*/
#define BZ_M_IDLE 1
#define BZ_M_RUNNING 2
#define BZ_M_FLUSHING 3
#define BZ_M_FINISHING 4
#define BZ_S_OUTPUT 1
#define BZ_S_INPUT 2
#define BZ_N_RADIX 2
#define BZ_N_QSORT 12
#define BZ_N_SHELL 18
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
/*-- Structure holding all the compression-side stuff. --*/
typedef
struct {
/* pointer back to the struct bz_stream */
bz_stream* strm;
/* mode this stream is in, and whether inputting */
/* or outputting data */
Int32 mode;
Int32 state;
/* remembers avail_in when flush/finish requested */
UInt32 avail_in_expect;
/* for doing the block sorting */
UInt32* arr1;
UInt32* arr2;
UInt32* ftab;
Int32 origPtr;
/* aliases for arr1 and arr2 */
UInt32* ptr;
UChar* block;
UInt16* mtfv;
UChar* zbits;
/* for deciding when to use the fallback sorting algorithm */
Int32 workFactor;
/* run-length-encoding of the input */
UInt32 state_in_ch;
Int32 state_in_len;
BZ_RAND_DECLS;
/* input and output limits and current posns */
Int32 nblock;
Int32 nblockMAX;
Int32 numZ;
Int32 state_out_pos;
/* map of bytes used in block */
Int32 nInUse;
Bool inUse[256];
UChar unseqToSeq[256];
/* the buffer for bit stream creation */
UInt32 bsBuff;
Int32 bsLive;
/* block and combined CRCs */
UInt32 blockCRC;
UInt32 combinedCRC;
/* misc administratium */
Int32 verbosity;
Int32 blockNo;
Int32 blockSize100k;
/* stuff for coding the MTF values */
Int32 nMTF;
Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
UChar selector [BZ_MAX_SELECTORS];
UChar selectorMtf[BZ_MAX_SELECTORS];
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
/* second dimension: only 3 needed; 4 makes index calculations faster */
UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
}
EState;
/*-- externs for compression. --*/
extern void
BZ2_blockSort ( EState* );
extern void
BZ2_compressBlock ( EState*, Bool );
extern void
BZ2_bsInitWrite ( EState* );
extern void
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
extern void
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
/*-- states for decompression. --*/
#define BZ_X_IDLE 1
#define BZ_X_OUTPUT 2
#define BZ_X_MAGIC_1 10
#define BZ_X_MAGIC_2 11
#define BZ_X_MAGIC_3 12
#define BZ_X_MAGIC_4 13
#define BZ_X_BLKHDR_1 14
#define BZ_X_BLKHDR_2 15
#define BZ_X_BLKHDR_3 16
#define BZ_X_BLKHDR_4 17
#define BZ_X_BLKHDR_5 18
#define BZ_X_BLKHDR_6 19
#define BZ_X_BCRC_1 20
#define BZ_X_BCRC_2 21
#define BZ_X_BCRC_3 22
#define BZ_X_BCRC_4 23
#define BZ_X_RANDBIT 24
#define BZ_X_ORIGPTR_1 25
#define BZ_X_ORIGPTR_2 26
#define BZ_X_ORIGPTR_3 27
#define BZ_X_MAPPING_1 28
#define BZ_X_MAPPING_2 29
#define BZ_X_SELECTOR_1 30
#define BZ_X_SELECTOR_2 31
#define BZ_X_SELECTOR_3 32
#define BZ_X_CODING_1 33
#define BZ_X_CODING_2 34
#define BZ_X_CODING_3 35
#define BZ_X_MTF_1 36
#define BZ_X_MTF_2 37
#define BZ_X_MTF_3 38
#define BZ_X_MTF_4 39
#define BZ_X_MTF_5 40
#define BZ_X_MTF_6 41
#define BZ_X_ENDHDR_2 42
#define BZ_X_ENDHDR_3 43
#define BZ_X_ENDHDR_4 44
#define BZ_X_ENDHDR_5 45
#define BZ_X_ENDHDR_6 46
#define BZ_X_CCRC_1 47
#define BZ_X_CCRC_2 48
#define BZ_X_CCRC_3 49
#define BZ_X_CCRC_4 50
/*-- Constants for the fast MTF decoder. --*/
#define MTFA_SIZE 4096
#define MTFL_SIZE 16
/*-- Structure holding all the decompression-side stuff. --*/
typedef
struct {
/* pointer back to the struct bz_stream */
bz_stream* strm;
/* state indicator for this stream */
Int32 state;
/* for doing the final run-length decoding */
UChar state_out_ch;
Int32 state_out_len;
Bool blockRandomised;
BZ_RAND_DECLS;
/* the buffer for bit stream reading */
UInt32 bsBuff;
Int32 bsLive;
/* misc administratium */
Int32 blockSize100k;
Bool smallDecompress;
Int32 currBlockNo;
Int32 verbosity;
/* for undoing the Burrows-Wheeler transform */
Int32 origPtr;
UInt32 tPos;
Int32 k0;
Int32 unzftab[256];
Int32 nblock_used;
Int32 cftab[257];
Int32 cftabCopy[257];
/* for undoing the Burrows-Wheeler transform (FAST) */
UInt32 *tt;
/* for undoing the Burrows-Wheeler transform (SMALL) */
UInt16 *ll16;
UChar *ll4;
/* stored and calculated CRCs */
UInt32 storedBlockCRC;
UInt32 storedCombinedCRC;
UInt32 calculatedBlockCRC;
UInt32 calculatedCombinedCRC;
/* map of bytes used in block */
Int32 nInUse;
Bool inUse[256];
Bool inUse16[16];
UChar seqToUnseq[256];
/* for decoding the MTF values */
UChar mtfa [MTFA_SIZE];
Int32 mtfbase[256 / MTFL_SIZE];
UChar selector [BZ_MAX_SELECTORS];
UChar selectorMtf[BZ_MAX_SELECTORS];
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 minLens[BZ_N_GROUPS];
/* save area for scalars in the main decompress code */
Int32 save_i;
Int32 save_j;
Int32 save_t;
Int32 save_alphaSize;
Int32 save_nGroups;
Int32 save_nSelectors;
Int32 save_EOB;
Int32 save_groupNo;
Int32 save_groupPos;
Int32 save_nextSym;
Int32 save_nblockMAX;
Int32 save_nblock;
Int32 save_es;
Int32 save_N;
Int32 save_curr;
Int32 save_zt;
Int32 save_zn;
Int32 save_zvec;
Int32 save_zj;
Int32 save_gSel;
Int32 save_gMinlen;
Int32* save_gLimit;
Int32* save_gBase;
Int32* save_gPerm;
}
DState;
/*-- Macros for decompression. --*/
#define BZ_GET_FAST(cccc) \
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
s->tPos = s->tt[s->tPos]; \
cccc = (UChar)(s->tPos & 0xff); \
s->tPos >>= 8;
#define BZ_GET_FAST_C(cccc) \
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
c_tPos = c_tt[c_tPos]; \
cccc = (UChar)(c_tPos & 0xff); \
c_tPos >>= 8;
#define SET_LL4(i,n) \
{ if (((i) & 0x1) == 0) \
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
}
#define GET_LL4(i) \
((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
#define SET_LL(i,n) \
{ s->ll16[i] = (UInt16)(n & 0x0000ffff); \
SET_LL4(i, n >> 16); \
}
#define GET_LL(i) \
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
#define BZ_GET_SMALL(cccc) \
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
s->tPos = GET_LL(s->tPos);
/*-- externs for decompression. --*/
extern Int32
BZ2_indexIntoF ( Int32, Int32* );
extern Int32
BZ2_decompress ( DState* );
extern void
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
Int32, Int32, Int32 );
#endif
/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
#ifdef BZ_NO_STDIO
#ifndef NULL
#define NULL 0
#endif
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib_private.h ---*/
/*-------------------------------------------------------------*/

View File

@@ -1,672 +0,0 @@
/*-------------------------------------------------------------*/
/*--- Compression machinery (not incl block sorting) ---*/
/*--- compress.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
/* CHANGES
0.9.0 -- original version.
0.9.0a/b -- no changes in this file.
0.9.0c -- changed setting of nGroups in sendMTFValues()
so as to do a bit better on small files
*/
#include "bzlib_private.h"
/*---------------------------------------------------*/
/*--- Bit stream I/O ---*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
void BZ2_bsInitWrite ( EState* s )
{
s->bsLive = 0;
s->bsBuff = 0;
}
/*---------------------------------------------------*/
static
void bsFinishWrite ( EState* s )
{
while (s->bsLive > 0) {
s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
s->numZ++;
s->bsBuff <<= 8;
s->bsLive -= 8;
}
}
/*---------------------------------------------------*/
#define bsNEEDW(nz) \
{ \
while (s->bsLive >= 8) { \
s->zbits[s->numZ] \
= (UChar)(s->bsBuff >> 24); \
s->numZ++; \
s->bsBuff <<= 8; \
s->bsLive -= 8; \
} \
}
/*---------------------------------------------------*/
static
__inline__
void bsW ( EState* s, Int32 n, UInt32 v )
{
bsNEEDW ( n );
s->bsBuff |= (v << (32 - s->bsLive - n));
s->bsLive += n;
}
/*---------------------------------------------------*/
static
void bsPutUInt32 ( EState* s, UInt32 u )
{
bsW ( s, 8, (u >> 24) & 0xffL );
bsW ( s, 8, (u >> 16) & 0xffL );
bsW ( s, 8, (u >> 8) & 0xffL );
bsW ( s, 8, u & 0xffL );
}
/*---------------------------------------------------*/
static
void bsPutUChar ( EState* s, UChar c )
{
bsW( s, 8, (UInt32)c );
}
/*---------------------------------------------------*/
/*--- The back end proper ---*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
static
void makeMaps_e ( EState* s )
{
Int32 i;
s->nInUse = 0;
for (i = 0; i < 256; i++)
if (s->inUse[i]) {
s->unseqToSeq[i] = s->nInUse;
s->nInUse++;
}
}
/*---------------------------------------------------*/
static
void generateMTFValues ( EState* s )
{
UChar yy[256];
Int32 i, j;
Int32 zPend;
Int32 wr;
Int32 EOB;
/*
After sorting (eg, here),
s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
and
((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
holds the original block data.
The first thing to do is generate the MTF values,
and put them in
((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
Because there are strictly fewer or equal MTF values
than block values, ptr values in this area are overwritten
with MTF values only when they are no longer needed.
The final compressed bitstream is generated into the
area starting at
(UChar*) (&((UChar*)s->arr2)[s->nblock])
These storage aliases are set up in bzCompressInit(),
except for the last one, which is arranged in
compressBlock().
*/
UInt32* ptr = s->ptr;
UChar* block = s->block;
UInt16* mtfv = s->mtfv;
makeMaps_e ( s );
EOB = s->nInUse+1;
for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
wr = 0;
zPend = 0;
for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
for (i = 0; i < s->nblock; i++) {
UChar ll_i;
AssertD ( wr <= i, "generateMTFValues(1)" );
j = ptr[i]-1; if (j < 0) j += s->nblock;
ll_i = s->unseqToSeq[block[j]];
AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
if (yy[0] == ll_i) {
zPend++;
} else {
if (zPend > 0) {
zPend--;
while (True) {
if (zPend & 1) {
mtfv[wr] = BZ_RUNB; wr++;
s->mtfFreq[BZ_RUNB]++;
} else {
mtfv[wr] = BZ_RUNA; wr++;
s->mtfFreq[BZ_RUNA]++;
}
if (zPend < 2) break;
zPend = (zPend - 2) / 2;
};
zPend = 0;
}
{
register UChar rtmp;
register UChar* ryy_j;
register UChar rll_i;
rtmp = yy[1];
yy[1] = yy[0];
ryy_j = &(yy[1]);
rll_i = ll_i;
while ( rll_i != rtmp ) {
register UChar rtmp2;
ryy_j++;
rtmp2 = rtmp;
rtmp = *ryy_j;
*ryy_j = rtmp2;
};
yy[0] = rtmp;
j = ryy_j - &(yy[0]);
mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
}
}
}
if (zPend > 0) {
zPend--;
while (True) {
if (zPend & 1) {
mtfv[wr] = BZ_RUNB; wr++;
s->mtfFreq[BZ_RUNB]++;
} else {
mtfv[wr] = BZ_RUNA; wr++;
s->mtfFreq[BZ_RUNA]++;
}
if (zPend < 2) break;
zPend = (zPend - 2) / 2;
};
zPend = 0;
}
mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
s->nMTF = wr;
}
/*---------------------------------------------------*/
#define BZ_LESSER_ICOST 0
#define BZ_GREATER_ICOST 15
static
void sendMTFValues ( EState* s )
{
Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
Int32 nGroups, nBytes;
/*--
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
is a global since the decoder also needs it.
Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
are also globals only used in this proc.
Made global to keep stack frame size small.
--*/
UInt16 cost[BZ_N_GROUPS];
Int32 fave[BZ_N_GROUPS];
UInt16* mtfv = s->mtfv;
if (s->verbosity >= 3)
VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
"%d+2 syms in use\n",
s->nblock, s->nMTF, s->nInUse );
alphaSize = s->nInUse+2;
for (t = 0; t < BZ_N_GROUPS; t++)
for (v = 0; v < alphaSize; v++)
s->len[t][v] = BZ_GREATER_ICOST;
/*--- Decide how many coding tables to use ---*/
AssertH ( s->nMTF > 0, 3001 );
if (s->nMTF < 200) nGroups = 2; else
if (s->nMTF < 600) nGroups = 3; else
if (s->nMTF < 1200) nGroups = 4; else
if (s->nMTF < 2400) nGroups = 5; else
nGroups = 6;
/*--- Generate an initial set of coding tables ---*/
{
Int32 nPart, remF, tFreq, aFreq;
nPart = nGroups;
remF = s->nMTF;
gs = 0;
while (nPart > 0) {
tFreq = remF / nPart;
ge = gs-1;
aFreq = 0;
while (aFreq < tFreq && ge < alphaSize-1) {
ge++;
aFreq += s->mtfFreq[ge];
}
if (ge > gs
&& nPart != nGroups && nPart != 1
&& ((nGroups-nPart) % 2 == 1)) {
aFreq -= s->mtfFreq[ge];
ge--;
}
if (s->verbosity >= 3)
VPrintf5( " initial group %d, [%d .. %d], "
"has %d syms (%4.1f%%)\n",
nPart, gs, ge, aFreq,
(100.0 * (float)aFreq) / (float)(s->nMTF) );
for (v = 0; v < alphaSize; v++)
if (v >= gs && v <= ge)
s->len[nPart-1][v] = BZ_LESSER_ICOST; else
s->len[nPart-1][v] = BZ_GREATER_ICOST;
nPart--;
gs = ge+1;
remF -= aFreq;
}
}
/*---
Iterate up to BZ_N_ITERS times to improve the tables.
---*/
for (iter = 0; iter < BZ_N_ITERS; iter++) {
for (t = 0; t < nGroups; t++) fave[t] = 0;
for (t = 0; t < nGroups; t++)
for (v = 0; v < alphaSize; v++)
s->rfreq[t][v] = 0;
/*---
Set up an auxiliary length table which is used to fast-track
the common case (nGroups == 6).
---*/
if (nGroups == 6) {
for (v = 0; v < alphaSize; v++) {
s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
}
}
nSelectors = 0;
totc = 0;
gs = 0;
while (True) {
/*--- Set group start & end marks. --*/
if (gs >= s->nMTF) break;
ge = gs + BZ_G_SIZE - 1;
if (ge >= s->nMTF) ge = s->nMTF-1;
/*--
Calculate the cost of this group as coded
by each of the coding tables.
--*/
for (t = 0; t < nGroups; t++) cost[t] = 0;
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
register UInt32 cost01, cost23, cost45;
register UInt16 icv;
cost01 = cost23 = cost45 = 0;
# define BZ_ITER(nn) \
icv = mtfv[gs+(nn)]; \
cost01 += s->len_pack[icv][0]; \
cost23 += s->len_pack[icv][1]; \
cost45 += s->len_pack[icv][2]; \
BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
# undef BZ_ITER
cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++) {
UInt16 icv = mtfv[i];
for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
}
}
/*--
Find the coding table which is best for this group,
and record its identity in the selector table.
--*/
bc = 999999999; bt = -1;
for (t = 0; t < nGroups; t++)
if (cost[t] < bc) { bc = cost[t]; bt = t; };
totc += bc;
fave[bt]++;
s->selector[nSelectors] = bt;
nSelectors++;
/*--
Increment the symbol frequencies for the selected table.
--*/
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
# undef BZ_ITUR
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++)
s->rfreq[bt][ mtfv[i] ]++;
}
gs = ge+1;
}
if (s->verbosity >= 3) {
VPrintf2 ( " pass %d: size is %d, grp uses are ",
iter+1, totc/8 );
for (t = 0; t < nGroups; t++)
VPrintf1 ( "%d ", fave[t] );
VPrintf0 ( "\n" );
}
/*--
Recompute the tables based on the accumulated frequencies.
--*/
/* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
comment in huffman.c for details. */
for (t = 0; t < nGroups; t++)
BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
alphaSize, 17 /*20*/ );
}
AssertH( nGroups < 8, 3002 );
AssertH( nSelectors < 32768 &&
nSelectors <= (2 + (900000 / BZ_G_SIZE)),
3003 );
/*--- Compute MTF values for the selectors. ---*/
{
UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
for (i = 0; i < nGroups; i++) pos[i] = i;
for (i = 0; i < nSelectors; i++) {
ll_i = s->selector[i];
j = 0;
tmp = pos[j];
while ( ll_i != tmp ) {
j++;
tmp2 = tmp;
tmp = pos[j];
pos[j] = tmp2;
};
pos[0] = tmp;
s->selectorMtf[i] = j;
}
};
/*--- Assign actual codes for the tables. --*/
for (t = 0; t < nGroups; t++) {
minLen = 32;
maxLen = 0;
for (i = 0; i < alphaSize; i++) {
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
if (s->len[t][i] < minLen) minLen = s->len[t][i];
}
AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
AssertH ( !(minLen < 1), 3005 );
BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
minLen, maxLen, alphaSize );
}
/*--- Transmit the mapping table. ---*/
{
Bool inUse16[16];
for (i = 0; i < 16; i++) {
inUse16[i] = False;
for (j = 0; j < 16; j++)
if (s->inUse[i * 16 + j]) inUse16[i] = True;
}
nBytes = s->numZ;
for (i = 0; i < 16; i++)
if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
for (i = 0; i < 16; i++)
if (inUse16[i])
for (j = 0; j < 16; j++) {
if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
}
if (s->verbosity >= 3)
VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
}
/*--- Now the selectors. ---*/
nBytes = s->numZ;
bsW ( s, 3, nGroups );
bsW ( s, 15, nSelectors );
for (i = 0; i < nSelectors; i++) {
for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
bsW(s,1,0);
}
if (s->verbosity >= 3)
VPrintf1( "selectors %d, ", s->numZ-nBytes );
/*--- Now the coding tables. ---*/
nBytes = s->numZ;
for (t = 0; t < nGroups; t++) {
Int32 curr = s->len[t][0];
bsW ( s, 5, curr );
for (i = 0; i < alphaSize; i++) {
while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
bsW ( s, 1, 0 );
}
}
if (s->verbosity >= 3)
VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
/*--- And finally, the block data proper ---*/
nBytes = s->numZ;
selCtr = 0;
gs = 0;
while (True) {
if (gs >= s->nMTF) break;
ge = gs + BZ_G_SIZE - 1;
if (ge >= s->nMTF) ge = s->nMTF-1;
AssertH ( s->selector[selCtr] < nGroups, 3006 );
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
UInt16 mtfv_i;
UChar* s_len_sel_selCtr
= &(s->len[s->selector[selCtr]][0]);
Int32* s_code_sel_selCtr
= &(s->code[s->selector[selCtr]][0]);
# define BZ_ITAH(nn) \
mtfv_i = mtfv[gs+(nn)]; \
bsW ( s, \
s_len_sel_selCtr[mtfv_i], \
s_code_sel_selCtr[mtfv_i] )
BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
# undef BZ_ITAH
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++) {
bsW ( s,
s->len [s->selector[selCtr]] [mtfv[i]],
s->code [s->selector[selCtr]] [mtfv[i]] );
}
}
gs = ge+1;
selCtr++;
}
AssertH( selCtr == nSelectors, 3007 );
if (s->verbosity >= 3)
VPrintf1( "codes %d\n", s->numZ-nBytes );
}
/*---------------------------------------------------*/
void BZ2_compressBlock ( EState* s, Bool is_last_block )
{
if (s->nblock > 0) {
BZ_FINALISE_CRC ( s->blockCRC );
s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
s->combinedCRC ^= s->blockCRC;
if (s->blockNo > 1) s->numZ = 0;
if (s->verbosity >= 2)
VPrintf4( " block %d: crc = 0x%08x, "
"combined CRC = 0x%08x, size = %d\n",
s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
BZ2_blockSort ( s );
}
s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
/*-- If this is the first block, create the stream header. --*/
if (s->blockNo == 1) {
BZ2_bsInitWrite ( s );
bsPutUChar ( s, BZ_HDR_B );
bsPutUChar ( s, BZ_HDR_Z );
bsPutUChar ( s, BZ_HDR_h );
bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
}
if (s->nblock > 0) {
bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
/*-- Now the block's CRC, so it is in a known place. --*/
bsPutUInt32 ( s, s->blockCRC );
/*--
Now a single bit indicating (non-)randomisation.
As of version 0.9.5, we use a better sorting algorithm
which makes randomisation unnecessary. So always set
the randomised bit to 'no'. Of course, the decoder
still needs to be able to handle randomised blocks
so as to maintain backwards compatibility with
older versions of bzip2.
--*/
bsW(s,1,0);
bsW ( s, 24, s->origPtr );
generateMTFValues ( s );
sendMTFValues ( s );
}
/*-- If this is the last block, add the stream trailer. --*/
if (is_last_block) {
bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
bsPutUInt32 ( s, s->combinedCRC );
if (s->verbosity >= 2)
VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
bsFinishWrite ( s );
}
}
/*-------------------------------------------------------------*/
/*--- end compress.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -1,104 +0,0 @@
/*-------------------------------------------------------------*/
/*--- Table for doing CRCs ---*/
/*--- crctable.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*--
I think this is an implementation of the AUTODIN-II,
Ethernet & FDDI 32-bit CRC standard. Vaguely derived
from code by Rob Warnock, in Section 51 of the
comp.compression FAQ.
--*/
UInt32 BZ2_crc32Table[256] = {
/*-- Ugly, innit? --*/
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
};
/*-------------------------------------------------------------*/
/*--- end crctable.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -1,646 +0,0 @@
/*-------------------------------------------------------------*/
/*--- Decompression machinery ---*/
/*--- decompress.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------------*/
static
void makeMaps_d ( DState* s )
{
Int32 i;
s->nInUse = 0;
for (i = 0; i < 256; i++)
if (s->inUse[i]) {
s->seqToUnseq[s->nInUse] = i;
s->nInUse++;
}
}
/*---------------------------------------------------*/
#define RETURN(rrr) \
{ retVal = rrr; goto save_state_and_return; };
#define GET_BITS(lll,vvv,nnn) \
case lll: s->state = lll; \
while (True) { \
if (s->bsLive >= nnn) { \
UInt32 v; \
v = (s->bsBuff >> \
(s->bsLive-nnn)) & ((1 << nnn)-1); \
s->bsLive -= nnn; \
vvv = v; \
break; \
} \
if (s->strm->avail_in == 0) RETURN(BZ_OK); \
s->bsBuff \
= (s->bsBuff << 8) | \
((UInt32) \
(*((UChar*)(s->strm->next_in)))); \
s->bsLive += 8; \
s->strm->next_in++; \
s->strm->avail_in--; \
s->strm->total_in_lo32++; \
if (s->strm->total_in_lo32 == 0) \
s->strm->total_in_hi32++; \
}
#define GET_UCHAR(lll,uuu) \
GET_BITS(lll,uuu,8)
#define GET_BIT(lll,uuu) \
GET_BITS(lll,uuu,1)
/*---------------------------------------------------*/
#define GET_MTF_VAL(label1,label2,lval) \
{ \
if (groupPos == 0) { \
groupNo++; \
if (groupNo >= nSelectors) \
RETURN(BZ_DATA_ERROR); \
groupPos = BZ_G_SIZE; \
gSel = s->selector[groupNo]; \
gMinlen = s->minLens[gSel]; \
gLimit = &(s->limit[gSel][0]); \
gPerm = &(s->perm[gSel][0]); \
gBase = &(s->base[gSel][0]); \
} \
groupPos--; \
zn = gMinlen; \
GET_BITS(label1, zvec, zn); \
while (1) { \
if (zn > 20 /* the longest code */) \
RETURN(BZ_DATA_ERROR); \
if (zvec <= gLimit[zn]) break; \
zn++; \
GET_BIT(label2, zj); \
zvec = (zvec << 1) | zj; \
}; \
if (zvec - gBase[zn] < 0 \
|| zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
RETURN(BZ_DATA_ERROR); \
lval = gPerm[zvec - gBase[zn]]; \
}
/*---------------------------------------------------*/
Int32 BZ2_decompress ( DState* s )
{
UChar uc;
Int32 retVal;
Int32 minLen, maxLen;
bz_stream* strm = s->strm;
/* stuff that needs to be saved/restored */
Int32 i;
Int32 j;
Int32 t;
Int32 alphaSize;
Int32 nGroups;
Int32 nSelectors;
Int32 EOB;
Int32 groupNo;
Int32 groupPos;
Int32 nextSym;
Int32 nblockMAX;
Int32 nblock;
Int32 es;
Int32 N;
Int32 curr;
Int32 zt;
Int32 zn;
Int32 zvec;
Int32 zj;
Int32 gSel;
Int32 gMinlen;
Int32* gLimit;
Int32* gBase;
Int32* gPerm;
if (s->state == BZ_X_MAGIC_1) {
/*initialise the save area*/
s->save_i = 0;
s->save_j = 0;
s->save_t = 0;
s->save_alphaSize = 0;
s->save_nGroups = 0;
s->save_nSelectors = 0;
s->save_EOB = 0;
s->save_groupNo = 0;
s->save_groupPos = 0;
s->save_nextSym = 0;
s->save_nblockMAX = 0;
s->save_nblock = 0;
s->save_es = 0;
s->save_N = 0;
s->save_curr = 0;
s->save_zt = 0;
s->save_zn = 0;
s->save_zvec = 0;
s->save_zj = 0;
s->save_gSel = 0;
s->save_gMinlen = 0;
s->save_gLimit = NULL;
s->save_gBase = NULL;
s->save_gPerm = NULL;
}
/*restore from the save area*/
i = s->save_i;
j = s->save_j;
t = s->save_t;
alphaSize = s->save_alphaSize;
nGroups = s->save_nGroups;
nSelectors = s->save_nSelectors;
EOB = s->save_EOB;
groupNo = s->save_groupNo;
groupPos = s->save_groupPos;
nextSym = s->save_nextSym;
nblockMAX = s->save_nblockMAX;
nblock = s->save_nblock;
es = s->save_es;
N = s->save_N;
curr = s->save_curr;
zt = s->save_zt;
zn = s->save_zn;
zvec = s->save_zvec;
zj = s->save_zj;
gSel = s->save_gSel;
gMinlen = s->save_gMinlen;
gLimit = s->save_gLimit;
gBase = s->save_gBase;
gPerm = s->save_gPerm;
retVal = BZ_OK;
switch (s->state) {
GET_UCHAR(BZ_X_MAGIC_1, uc);
if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
GET_UCHAR(BZ_X_MAGIC_2, uc);
if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
GET_UCHAR(BZ_X_MAGIC_3, uc)
if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
if (s->blockSize100k < (BZ_HDR_0 + 1) ||
s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
s->blockSize100k -= BZ_HDR_0;
if (s->smallDecompress) {
s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
s->ll4 = BZALLOC(
((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
);
if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
} else {
s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
}
GET_UCHAR(BZ_X_BLKHDR_1, uc);
if (uc == 0x17) goto endhdr_2;
if (uc != 0x31) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_2, uc);
if (uc != 0x41) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_3, uc);
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_4, uc);
if (uc != 0x26) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_5, uc);
if (uc != 0x53) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_6, uc);
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
s->currBlockNo++;
if (s->verbosity >= 2)
VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
s->storedBlockCRC = 0;
GET_UCHAR(BZ_X_BCRC_1, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_2, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_3, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_4, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
s->origPtr = 0;
GET_UCHAR(BZ_X_ORIGPTR_1, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
GET_UCHAR(BZ_X_ORIGPTR_2, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
GET_UCHAR(BZ_X_ORIGPTR_3, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
if (s->origPtr < 0)
RETURN(BZ_DATA_ERROR);
if (s->origPtr > 10 + 100000*s->blockSize100k)
RETURN(BZ_DATA_ERROR);
/*--- Receive the mapping table ---*/
for (i = 0; i < 16; i++) {
GET_BIT(BZ_X_MAPPING_1, uc);
if (uc == 1)
s->inUse16[i] = True; else
s->inUse16[i] = False;
}
for (i = 0; i < 256; i++) s->inUse[i] = False;
for (i = 0; i < 16; i++)
if (s->inUse16[i])
for (j = 0; j < 16; j++) {
GET_BIT(BZ_X_MAPPING_2, uc);
if (uc == 1) s->inUse[i * 16 + j] = True;
}
makeMaps_d ( s );
if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
alphaSize = s->nInUse+2;
/*--- Now the selectors ---*/
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
for (i = 0; i < nSelectors; i++) {
j = 0;
while (True) {
GET_BIT(BZ_X_SELECTOR_3, uc);
if (uc == 0) break;
j++;
if (j >= nGroups) RETURN(BZ_DATA_ERROR);
}
s->selectorMtf[i] = j;
}
/*--- Undo the MTF values for the selectors. ---*/
{
UChar pos[BZ_N_GROUPS], tmp, v;
for (v = 0; v < nGroups; v++) pos[v] = v;
for (i = 0; i < nSelectors; i++) {
v = s->selectorMtf[i];
tmp = pos[v];
while (v > 0) { pos[v] = pos[v-1]; v--; }
pos[0] = tmp;
s->selector[i] = tmp;
}
}
/*--- Now the coding tables ---*/
for (t = 0; t < nGroups; t++) {
GET_BITS(BZ_X_CODING_1, curr, 5);
for (i = 0; i < alphaSize; i++) {
while (True) {
if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
GET_BIT(BZ_X_CODING_2, uc);
if (uc == 0) break;
GET_BIT(BZ_X_CODING_3, uc);
if (uc == 0) curr++; else curr--;
}
s->len[t][i] = curr;
}
}
/*--- Create the Huffman decoding tables ---*/
for (t = 0; t < nGroups; t++) {
minLen = 32;
maxLen = 0;
for (i = 0; i < alphaSize; i++) {
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
if (s->len[t][i] < minLen) minLen = s->len[t][i];
}
BZ2_hbCreateDecodeTables (
&(s->limit[t][0]),
&(s->base[t][0]),
&(s->perm[t][0]),
&(s->len[t][0]),
minLen, maxLen, alphaSize
);
s->minLens[t] = minLen;
}
/*--- Now the MTF values ---*/
EOB = s->nInUse+1;
nblockMAX = 100000 * s->blockSize100k;
groupNo = -1;
groupPos = 0;
for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
/*-- MTF init --*/
{
Int32 ii, jj, kk;
kk = MTFA_SIZE-1;
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
kk--;
}
s->mtfbase[ii] = kk + 1;
}
}
/*-- end MTF init --*/
nblock = 0;
GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
while (True) {
if (nextSym == EOB) break;
if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
es = -1;
N = 1;
do {
/* Check that N doesn't get too big, so that es doesn't
go negative. The maximum value that can be
RUNA/RUNB encoded is equal to the block size (post
the initial RLE), viz, 900k, so bounding N at 2
million should guard against overflow without
rejecting any legitimate inputs. */
if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
N = N * 2;
GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
}
while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
es++;
uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
s->unzftab[uc] += es;
if (s->smallDecompress)
while (es > 0) {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
s->ll16[nblock] = (UInt16)uc;
nblock++;
es--;
}
else
while (es > 0) {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
s->tt[nblock] = (UInt32)uc;
nblock++;
es--;
};
continue;
} else {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
/*-- uc = MTF ( nextSym-1 ) --*/
{
Int32 ii, jj, kk, pp, lno, off;
UInt32 nn;
nn = (UInt32)(nextSym - 1);
if (nn < MTFL_SIZE) {
/* avoid general-case expense */
pp = s->mtfbase[0];
uc = s->mtfa[pp+nn];
while (nn > 3) {
Int32 z = pp+nn;
s->mtfa[(z) ] = s->mtfa[(z)-1];
s->mtfa[(z)-1] = s->mtfa[(z)-2];
s->mtfa[(z)-2] = s->mtfa[(z)-3];
s->mtfa[(z)-3] = s->mtfa[(z)-4];
nn -= 4;
}
while (nn > 0) {
s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
};
s->mtfa[pp] = uc;
} else {
/* general case */
lno = nn / MTFL_SIZE;
off = nn % MTFL_SIZE;
pp = s->mtfbase[lno] + off;
uc = s->mtfa[pp];
while (pp > s->mtfbase[lno]) {
s->mtfa[pp] = s->mtfa[pp-1]; pp--;
};
s->mtfbase[lno]++;
while (lno > 0) {
s->mtfbase[lno]--;
s->mtfa[s->mtfbase[lno]]
= s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
lno--;
}
s->mtfbase[0]--;
s->mtfa[s->mtfbase[0]] = uc;
if (s->mtfbase[0] == 0) {
kk = MTFA_SIZE-1;
for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
kk--;
}
s->mtfbase[ii] = kk + 1;
}
}
}
}
/*-- end uc = MTF ( nextSym-1 ) --*/
s->unzftab[s->seqToUnseq[uc]]++;
if (s->smallDecompress)
s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
nblock++;
GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
continue;
}
}
/* Now we know what nblock is, we can do a better sanity
check on s->origPtr.
*/
if (s->origPtr < 0 || s->origPtr >= nblock)
RETURN(BZ_DATA_ERROR);
/*-- Set up cftab to facilitate generation of T^(-1) --*/
/* Check: unzftab entries in range. */
for (i = 0; i <= 255; i++) {
if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
RETURN(BZ_DATA_ERROR);
}
/* Actually generate cftab. */
s->cftab[0] = 0;
for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
/* Check: cftab entries in range. */
for (i = 0; i <= 256; i++) {
if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
/* s->cftab[i] can legitimately be == nblock */
RETURN(BZ_DATA_ERROR);
}
}
/* Check: cftab entries non-descending. */
for (i = 1; i <= 256; i++) {
if (s->cftab[i-1] > s->cftab[i]) {
RETURN(BZ_DATA_ERROR);
}
}
s->state_out_len = 0;
s->state_out_ch = 0;
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
s->state = BZ_X_OUTPUT;
if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
if (s->smallDecompress) {
/*-- Make a copy of cftab, used in generation of T --*/
for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
/*-- compute the T vector --*/
for (i = 0; i < nblock; i++) {
uc = (UChar)(s->ll16[i]);
SET_LL(i, s->cftabCopy[uc]);
s->cftabCopy[uc]++;
}
/*-- Compute T^(-1) by pointer reversal on T --*/
i = s->origPtr;
j = GET_LL(i);
do {
Int32 tmp = GET_LL(j);
SET_LL(j, i);
i = j;
j = tmp;
}
while (i != s->origPtr);
s->tPos = s->origPtr;
s->nblock_used = 0;
if (s->blockRandomised) {
BZ_RAND_INIT_MASK;
BZ_GET_SMALL(s->k0); s->nblock_used++;
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
} else {
BZ_GET_SMALL(s->k0); s->nblock_used++;
}
} else {
/*-- compute the T^(-1) vector --*/
for (i = 0; i < nblock; i++) {
uc = (UChar)(s->tt[i] & 0xff);
s->tt[s->cftab[uc]] |= (i << 8);
s->cftab[uc]++;
}
s->tPos = s->tt[s->origPtr] >> 8;
s->nblock_used = 0;
if (s->blockRandomised) {
BZ_RAND_INIT_MASK;
BZ_GET_FAST(s->k0); s->nblock_used++;
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
} else {
BZ_GET_FAST(s->k0); s->nblock_used++;
}
}
RETURN(BZ_OK);
endhdr_2:
GET_UCHAR(BZ_X_ENDHDR_2, uc);
if (uc != 0x72) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_3, uc);
if (uc != 0x45) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_4, uc);
if (uc != 0x38) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_5, uc);
if (uc != 0x50) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_6, uc);
if (uc != 0x90) RETURN(BZ_DATA_ERROR);
s->storedCombinedCRC = 0;
GET_UCHAR(BZ_X_CCRC_1, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_2, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_3, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_4, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
s->state = BZ_X_IDLE;
RETURN(BZ_STREAM_END);
default: AssertH ( False, 4001 );
}
AssertH ( False, 4002 );
save_state_and_return:
s->save_i = i;
s->save_j = j;
s->save_t = t;
s->save_alphaSize = alphaSize;
s->save_nGroups = nGroups;
s->save_nSelectors = nSelectors;
s->save_EOB = EOB;
s->save_groupNo = groupNo;
s->save_groupPos = groupPos;
s->save_nextSym = nextSym;
s->save_nblockMAX = nblockMAX;
s->save_nblock = nblock;
s->save_es = es;
s->save_N = N;
s->save_curr = curr;
s->save_zt = zt;
s->save_zn = zn;
s->save_zvec = zvec;
s->save_zj = zj;
s->save_gSel = gSel;
s->save_gMinlen = gMinlen;
s->save_gLimit = gLimit;
s->save_gBase = gBase;
s->save_gPerm = gPerm;
return retVal;
}
/*-------------------------------------------------------------*/
/*--- end decompress.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -1,205 +0,0 @@
/*-------------------------------------------------------------*/
/*--- Huffman coding low-level stuff ---*/
/*--- huffman.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------------*/
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
#define ADDWEIGHTS(zw1,zw2) \
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
#define UPHEAP(z) \
{ \
Int32 zz, tmp; \
zz = z; tmp = heap[zz]; \
while (weight[tmp] < weight[heap[zz >> 1]]) { \
heap[zz] = heap[zz >> 1]; \
zz >>= 1; \
} \
heap[zz] = tmp; \
}
#define DOWNHEAP(z) \
{ \
Int32 zz, yy, tmp; \
zz = z; tmp = heap[zz]; \
while (True) { \
yy = zz << 1; \
if (yy > nHeap) break; \
if (yy < nHeap && \
weight[heap[yy+1]] < weight[heap[yy]]) \
yy++; \
if (weight[tmp] < weight[heap[yy]]) break; \
heap[zz] = heap[yy]; \
zz = yy; \
} \
heap[zz] = tmp; \
}
/*---------------------------------------------------*/
void BZ2_hbMakeCodeLengths ( UChar *len,
Int32 *freq,
Int32 alphaSize,
Int32 maxLen )
{
/*--
Nodes and heap entries run from 1. Entry 0
for both the heap and nodes is a sentinel.
--*/
Int32 nNodes, nHeap, n1, n2, i, j, k;
Bool tooLong;
Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
for (i = 0; i < alphaSize; i++)
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
while (True) {
nNodes = alphaSize;
nHeap = 0;
heap[0] = 0;
weight[0] = 0;
parent[0] = -2;
for (i = 1; i <= alphaSize; i++) {
parent[i] = -1;
nHeap++;
heap[nHeap] = i;
UPHEAP(nHeap);
}
AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
while (nHeap > 1) {
n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
nNodes++;
parent[n1] = parent[n2] = nNodes;
weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
parent[nNodes] = -1;
nHeap++;
heap[nHeap] = nNodes;
UPHEAP(nHeap);
}
AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
tooLong = False;
for (i = 1; i <= alphaSize; i++) {
j = 0;
k = i;
while (parent[k] >= 0) { k = parent[k]; j++; }
len[i-1] = j;
if (j > maxLen) tooLong = True;
}
if (! tooLong) break;
/* 17 Oct 04: keep-going condition for the following loop used
to be 'i < alphaSize', which missed the last element,
theoretically leading to the possibility of the compressor
looping. However, this count-scaling step is only needed if
one of the generated Huffman code words is longer than
maxLen, which up to and including version 1.0.2 was 20 bits,
which is extremely unlikely. In version 1.0.3 maxLen was
changed to 17 bits, which has minimal effect on compression
ratio, but does mean this scaling step is used from time to
time, enough to verify that it works.
This means that bzip2-1.0.3 and later will only produce
Huffman codes with a maximum length of 17 bits. However, in
order to preserve backwards compatibility with bitstreams
produced by versions pre-1.0.3, the decompressor must still
handle lengths of up to 20. */
for (i = 1; i <= alphaSize; i++) {
j = weight[i] >> 8;
j = 1 + (j / 2);
weight[i] = j << 8;
}
}
}
/*---------------------------------------------------*/
void BZ2_hbAssignCodes ( Int32 *code,
UChar *length,
Int32 minLen,
Int32 maxLen,
Int32 alphaSize )
{
Int32 n, vec, i;
vec = 0;
for (n = minLen; n <= maxLen; n++) {
for (i = 0; i < alphaSize; i++)
if (length[i] == n) { code[i] = vec; vec++; };
vec <<= 1;
}
}
/*---------------------------------------------------*/
void BZ2_hbCreateDecodeTables ( Int32 *limit,
Int32 *base,
Int32 *perm,
UChar *length,
Int32 minLen,
Int32 maxLen,
Int32 alphaSize )
{
Int32 pp, i, j, vec;
pp = 0;
for (i = minLen; i <= maxLen; i++)
for (j = 0; j < alphaSize; j++)
if (length[j] == i) { perm[pp] = j; pp++; };
for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
vec = 0;
for (i = minLen; i <= maxLen; i++) {
vec += (base[i+1] - base[i]);
limit[i] = vec-1;
vec <<= 1;
}
for (i = minLen + 1; i <= maxLen; i++)
base[i] = ((limit[i-1] + 1) << 1) - base[i];
}
/*-------------------------------------------------------------*/
/*--- end huffman.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -1,84 +0,0 @@
/*-------------------------------------------------------------*/
/*--- Table for randomising repetitive blocks ---*/
/*--- randtable.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------*/
Int32 BZ2_rNums[512] = {
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
936, 638
};
/*-------------------------------------------------------------*/
/*--- end randtable.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -1 +0,0 @@
bzip2-1.0.6

View File

@@ -1,112 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*/
#include "universal.h"
#if SUPPORT_CRC32
void MojoCrc32_init(MojoCrc32 *context)
{
*context = (MojoCrc32) 0xFFFFFFFF;
} // MojoCrc32_init
void MojoCrc32_append(MojoCrc32 *_crc, const uint8 *buf, uint32 len)
{
uint32 crc = (uint32) *_crc;
uint32 n;
for (n = 0; n < len; n++)
{
uint32 xorval = (uint32) ((crc ^ buf[n]) & 0xFF);
xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
crc = xorval ^ (crc >> 8);
} // for
*_crc = (MojoCrc32) crc;
} // MojoCrc32_append
void MojoCrc32_finish(MojoCrc32 *context, uint32 *digest)
{
*digest = (*context ^ 0xFFFFFFFF);
} // MojoCrc32_finish
#endif // SUPPORT_CRC32
#if TEST_CRC32
int main(int argc, char **argv)
{
int i = 0;
for (i = 1; i < argc; i++)
{
FILE *in = NULL;
MojoCrc32 ctx;
MojoCrc32_init(&ctx);
in = fopen(argv[i], "rb");
if (!in)
perror("fopen");
else
{
uint32 digest = 0;
int err = 0;
while ( (!err) && (!feof(in)) )
{
uint8 buf[1024];
size_t rc = fread(buf, 1, sizeof (buf), in);
if (rc > 0)
MojoCrc32_append(&ctx, buf, rc);
err = ferror(in);
} // while
if (err)
perror("fread");
fclose(in);
MojoCrc32_finish(&ctx, &digest);
if (!err)
printf("%s: %X\n", argv[i], (unsigned int) digest);
} // else
} // for
return 0;
} // main
#endif
// end of checksum_crc32.c ...

View File

@@ -1,449 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
#include "universal.h"
#if SUPPORT_MD5
// MD5 code originally from http://sourceforge.net/projects/libmd5-rfc/
// License: zlib.
// I cleaned it up a little for MojoSetup's specific purposes. --ryan.
/*
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
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.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.c is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
either statically or dynamically; added missing #include <string.h>
in library.
2002-03-11 lpd Corrected argument list for main(), and added int return
type, in test program and T value program.
2002-02-21 lpd Added missing #include <stdio.h> in test program.
2000-07-03 lpd Patched to eliminate warnings about "constant is
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
*/
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
//#ifdef ARCH_IS_BIG_ENDIAN
//# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
//#else
//# define BYTE_ORDER 0
//#endif
#if PLATFORM_BIGENDIAN
# define BYTE_ORDER 1
#else
# define BYTE_ORDER -1
#endif
#define T_MASK ((uint32)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
static void
MojoMd5_process(MojoMd5 *pms, const uint8 *data /*[64]*/)
{
uint32
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
uint32 t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
uint32 X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
uint32 xbuf[16];
const uint32 *X;
#endif
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const uint8 *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const uint8 *)0) & 3)) {
/* data are properly aligned */
X = (const uint32 *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const uint8 *xp = data;
int i;
# if BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
# else
# define xbuf X /* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
SET(c, d, a, b, 2, 17, T3);
SET(b, c, d, a, 3, 22, T4);
SET(a, b, c, d, 4, 7, T5);
SET(d, a, b, c, 5, 12, T6);
SET(c, d, a, b, 6, 17, T7);
SET(b, c, d, a, 7, 22, T8);
SET(a, b, c, d, 8, 7, T9);
SET(d, a, b, c, 9, 12, T10);
SET(c, d, a, b, 10, 17, T11);
SET(b, c, d, a, 11, 22, T12);
SET(a, b, c, d, 12, 7, T13);
SET(d, a, b, c, 13, 12, T14);
SET(c, d, a, b, 14, 17, T15);
SET(b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
SET(c, d, a, b, 11, 14, T19);
SET(b, c, d, a, 0, 20, T20);
SET(a, b, c, d, 5, 5, T21);
SET(d, a, b, c, 10, 9, T22);
SET(c, d, a, b, 15, 14, T23);
SET(b, c, d, a, 4, 20, T24);
SET(a, b, c, d, 9, 5, T25);
SET(d, a, b, c, 14, 9, T26);
SET(c, d, a, b, 3, 14, T27);
SET(b, c, d, a, 8, 20, T28);
SET(a, b, c, d, 13, 5, T29);
SET(d, a, b, c, 2, 9, T30);
SET(c, d, a, b, 7, 14, T31);
SET(b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, T33);
SET(d, a, b, c, 8, 11, T34);
SET(c, d, a, b, 11, 16, T35);
SET(b, c, d, a, 14, 23, T36);
SET(a, b, c, d, 1, 4, T37);
SET(d, a, b, c, 4, 11, T38);
SET(c, d, a, b, 7, 16, T39);
SET(b, c, d, a, 10, 23, T40);
SET(a, b, c, d, 13, 4, T41);
SET(d, a, b, c, 0, 11, T42);
SET(c, d, a, b, 3, 16, T43);
SET(b, c, d, a, 6, 23, T44);
SET(a, b, c, d, 9, 4, T45);
SET(d, a, b, c, 12, 11, T46);
SET(c, d, a, b, 15, 16, T47);
SET(b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
SET(c, d, a, b, 14, 15, T51);
SET(b, c, d, a, 5, 21, T52);
SET(a, b, c, d, 12, 6, T53);
SET(d, a, b, c, 3, 10, T54);
SET(c, d, a, b, 10, 15, T55);
SET(b, c, d, a, 1, 21, T56);
SET(a, b, c, d, 8, 6, T57);
SET(d, a, b, c, 15, 10, T58);
SET(c, d, a, b, 6, 15, T59);
SET(b, c, d, a, 13, 21, T60);
SET(a, b, c, d, 4, 6, T61);
SET(d, a, b, c, 11, 10, T62);
SET(c, d, a, b, 2, 15, T63);
SET(b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void
MojoMd5_init(MojoMd5 *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
void
MojoMd5_append(MojoMd5 *pms, const uint8 *data, int nbytes)
{
const uint8 *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
uint32 nbits = (uint32)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
MojoMd5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
MojoMd5_process(pms, p);
/* Process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
}
void
MojoMd5_finish(MojoMd5 *pms, uint8 digest[16])
{
const uint8 pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
uint8 data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (uint8)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
MojoMd5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
MojoMd5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (uint8)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
#endif // SUPPORT_MD5
#if TEST_MD5
int main(int argc, char **argv)
{
int i = 0;
for (i = 1; i < argc; i++)
{
FILE *in = NULL;
MojoMd5 ctx;
MojoMd5_init(&ctx);
in = fopen(argv[i], "rb");
if (!in)
perror("fopen");
else
{
uint8 dig[16];
int err = 0;
while ( (!err) && (!feof(in)) )
{
uint8 buf[1024];
size_t rc = fread(buf, 1, sizeof (buf), in);
if (rc > 0)
MojoMd5_append(&ctx, buf, rc);
err = ferror(in);
} // while
if (err)
perror("fread");
fclose(in);
MojoMd5_finish(&ctx, dig);
if (!err)
{
printf("%s: %x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x\n", argv[i],
(int) dig[0], (int) dig[1], (int) dig[2], (int) dig[3],
(int) dig[4], (int) dig[5], (int) dig[6], (int) dig[7],
(int) dig[8], (int) dig[9], (int) dig[10], (int) dig[11],
(int) dig[12], (int) dig[13], (int) dig[14], (int) dig[15]);
} // if
} // else
} // for
return 0;
} // main
#endif
// end of checksum_md5.c ...

View File

@@ -1,238 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*
*/
#include "universal.h"
#if SUPPORT_SHA1
// SHA-1 code originally from ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
// License: public domain.
// I cleaned it up a little for MojoSetup's specific purposes. --ryan.
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#if PLATFORM_LITTLEENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#else
#define blk0(i) block->l[i]
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
static void MojoSha1_transform(uint32 state[5], const uint8 buffer[64])
{
uint32 a, b, c, d, e;
typedef union {
uint8 c[64];
uint32 l[16];
} CHAR64LONG16;
CHAR64LONG16* block;
static uint8 workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
}
/* MojoSha1_init - Initialize new context */
void MojoSha1_init(MojoSha1 *context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void MojoSha1_append(MojoSha1 *context, const uint8 *data, uint32 len)
{
uint32 i, j;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
MojoSha1_transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
MojoSha1_transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void MojoSha1_finish(MojoSha1 *context, uint8 digest[20])
{
uint32 i;
uint8 finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (uint8)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
MojoSha1_append(context, (uint8 *)"\200", 1);
while ((context->count[0] & 504) != 448) {
MojoSha1_append(context, (uint8 *)"\0", 1);
}
MojoSha1_append(context, finalcount, 8); /* Should cause a MojoSha1_transform() */
for (i = 0; i < 20; i++) {
digest[i] = (uint8)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
/* Wipe variables */
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(&finalcount, 0, 8);
MojoSha1_transform(context->state, context->buffer);
}
#endif // SUPPORT_SHA1
#if TEST_SHA1
int main(int argc, char **argv)
{
int i = 0;
for (i = 1; i < argc; i++)
{
FILE *in = NULL;
MojoSha1 ctx;
MojoSha1_init(&ctx);
in = fopen(argv[i], "rb");
if (!in)
perror("fopen");
else
{
uint8 dig[20];
int err = 0;
while ( (!err) && (!feof(in)) )
{
uint8 buf[1024];
size_t rc = fread(buf, 1, sizeof (buf), in);
if (rc > 0)
MojoSha1_append(&ctx, buf, rc);
err = ferror(in);
} // while
if (err)
perror("fread");
fclose(in);
MojoSha1_finish(&ctx, dig);
if (!err)
{
printf("%s: %x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x\n",
argv[i],
(int) dig[0], (int) dig[1], (int) dig[2], (int) dig[3],
(int) dig[4], (int) dig[5], (int) dig[6], (int) dig[7],
(int) dig[8], (int) dig[9], (int) dig[10], (int) dig[11],
(int) dig[12], (int) dig[13], (int) dig[14], (int) dig[15],
(int) dig[16], (int) dig[17], (int) dig[18], (int) dig[19]);
} // if
} // else
} // for
return 0;
} // main
#endif
// end of checksum_sha1.c ...

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,182 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*
*/
#ifndef _INCL_FILEIO_H_
#define _INCL_FILEIO_H_
#include "universal.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* File i/o may go through multiple layers: the archive attached to the binary,
* then an archive in there that's being read entirely out of memory that's
* being uncompressed to on the fly, or it might be a straight read from a
* regular uncompressed file on physical media. It might be a single file
* compressed with bzip2. As such, we have to have an abstraction over the
* usual channels...basically what we need here is archives-within-archives,
* done transparently and with arbitrary depth, although usually not more
* than one deep. This also works as a general transport layer, so the
* abstraction could be extended to network connections and such, too.
*/
// Abstract input interface. Files, memory, archive entries, etc.
typedef struct MojoInput MojoInput;
struct MojoInput
{
// public
boolean (*ready)(MojoInput *io);
int64 (*read)(MojoInput *io, void *buf, uint32 bufsize);
boolean (*seek)(MojoInput *io, uint64 pos);
int64 (*tell)(MojoInput *io);
int64 (*length)(MojoInput *io);
MojoInput* (*duplicate)(MojoInput *io);
void (*close)(MojoInput *io);
// private
void *opaque;
};
// If constant == 0, then this copies the memory, so you may free (ptr) after
// this function returns in that case.
MojoInput *MojoInput_newFromMemory(const uint8 *ptr, uint32 len, int constant);
// Get a MojoInput for a real file in the physical filesystem.
MojoInput *MojoInput_newFromFile(const char *fname);
// Make a subset range of (io) look like the entire file. This will take over
// control of (io), closing it when done, so never reference (io) directly
// again, if this call succeeds.
MojoInput *MojoInput_newFromSubset(MojoInput *io, const uint64 start,
const uint64 end);
typedef enum
{
MOJOARCHIVE_ENTRY_UNKNOWN = 0,
MOJOARCHIVE_ENTRY_FILE,
MOJOARCHIVE_ENTRY_DIR,
MOJOARCHIVE_ENTRY_SYMLINK,
} MojoArchiveEntryType;
// Abstract archive interface. Archives, directories, etc.
typedef struct MojoArchiveEntry
{
char *filename;
char *linkdest;
MojoArchiveEntryType type;
int64 filesize;
uint16 perms;
} MojoArchiveEntry;
void MojoArchive_resetEntry(MojoArchiveEntry *info);
typedef struct MojoArchive MojoArchive;
struct MojoArchive
{
// public
boolean (*enumerate)(MojoArchive *ar);
const MojoArchiveEntry* (*enumNext)(MojoArchive *ar);
MojoInput* (*openCurrentEntry)(MojoArchive *ar);
void (*close)(MojoArchive *ar);
// private
MojoInput *io;
MojoArchiveEntry prevEnum;
int64 offsetOfStart; // byte offset in MojoInput where archive starts.
void *opaque;
};
MojoArchive *MojoArchive_newFromDirectory(const char *dirname);
MojoArchive *MojoArchive_newFromInput(MojoInput *io, const char *origfname);
// This will reset enumeration in the archive, don't use it while iterating!
// Also, this can be very slow depending on the archive in question, so
// try to limit your random access filename lookups to known-fast quantities
// (like directories on the physical filesystem or a zipfile...tarballs and
// zipfiles-in-zipfiles will bog down here, for example).
MojoInput *MojoInput_newFromArchivePath(MojoArchive *ar, const char *fname);
// Wrap (origio) in a new MojoInput that decompresses a compressed stream
// on the fly. Returns NULL on error or if (origio) isn't a supported
// compressed format. The returned MojoInput wraps the original input;
// closing the returned MojoInput will close (origio), too, and you should
// consider origio lost. If this function returns non-NULL, you should not,
// under any circumstances, interact directly with origio again, as the
// new MojoInput now owns it.
MojoInput *MojoInput_newCompressedStream(MojoInput *origio);
// !!! FIXME: fill in missing documentation here.
extern MojoArchive *GBaseArchive;
extern const char *GBaseArchivePath;
MojoArchive *MojoArchive_initBaseArchive(void);
void MojoArchive_deinitBaseArchive(void);
typedef boolean (*MojoInput_FileCopyCallback)(uint32 ticks, int64 justwrote,
int64 bw, int64 total, void *data);
boolean MojoInput_toPhysicalFile(MojoInput *in, const char *fname, uint16 perms,
MojoChecksums *checksums, int64 maxbytes,
MojoInput_FileCopyCallback cb, void *data);
MojoInput *MojoInput_newFromURL(const char *url);
// Read a littleendian, unsigned 16-bit integer from (io), swapping it to
// the correct byteorder for the platform, and moving the file pointer
// ahead 2 bytes. Returns true on successful read and fills the swapped
// value into (*ui16), false on i/o error or EOF.
boolean MojoInput_readui16(MojoInput *io, uint16 *ui16);
// Read a littleendian, unsigned 32-bit integer from (io), swapping it to
// the correct byteorder for the platform, and moving the file pointer
// ahead 4 bytes. Returns true on successful read and fills the swapped
// value into (*ui32), false on i/o error or EOF.
boolean MojoInput_readui32(MojoInput *io, uint32 *ui32);
// Read a littleendian, unsigned 64-bit integer from (io), swapping it to
// the correct byteorder for the platform, and moving the file pointer
// ahead 8 bytes. Returns true on successful read and fills the swapped
// value into (*ui64), false on i/o error or EOF.
boolean MojoInput_readui64(MojoInput *io, uint64 *ui64);
// (Please note that there are not bigendian versions of MojoInput_readuiXX()
// at the moment, as we don't need them for our current feature set. However,
// they could be added easily enough.)
#ifdef __cplusplus
}
#endif
#endif
// end of fileio.h ...

View File

@@ -1,243 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*
*/
#include "gui.h"
#include "platform.h"
#include "fileio.h"
typedef struct S_PLUGINLIST
{
void *lib;
const MojoGui *gui;
MojoGuiPluginPriority priority;
struct S_PLUGINLIST *next;
} PluginList;
const MojoGui *GGui = NULL;
static PluginList *pluginDetails = NULL;
static const MojoGuiEntryPoint staticGui[] =
{
#if GUI_STATIC_LINK_STDIO
MojoGuiPlugin_stdio,
#endif
#if GUI_STATIC_LINK_COCOA
MojoGuiPlugin_cocoa,
#endif
#if GUI_STATIC_LINK_GTKPLUS2
MojoGuiPlugin_gtkplus2,
#endif
#if GUI_STATIC_LINK_WWW
MojoGuiPlugin_www,
#endif
#if GUI_STATIC_LINK_NCURSES
MojoGuiPlugin_ncurses,
#endif
NULL
};
static MojoGuiPluginPriority calcGuiPriority(const MojoGui *gui)
{
MojoGuiPluginPriority retval;
retval = gui->priority(MojoPlatform_istty());
// If the plugin isn't saying "don't try me at all" then see if the
// user explicitly wants this one.
if (retval != MOJOGUI_PRIORITY_NEVER_TRY)
{
static const char *envr = NULL;
if (envr == NULL)
envr = cmdlinestr("ui", "MOJOSETUP_UI", NULL);
if ((envr != NULL) && (strcasecmp(envr, gui->name()) == 0))
retval = MOJOGUI_PRIORITY_USER_REQUESTED;
} // if
return retval;
} // calcGuiPriority
static PluginList *initGuiPluginsByPriority(PluginList *plugins)
{
MojoGuiPluginPriority p;
for (p = MOJOGUI_PRIORITY_USER_REQUESTED; p < MOJOGUI_PRIORITY_TOTAL; p++)
{
PluginList *i;
for (i = plugins->next; i != NULL; i = i->next)
{
if ( (i->priority == p) && (i->gui->init()) )
{
logInfo("Selected '%0' UI.", i->gui->name());
return i;
} // if
} // for
} // for
return NULL;
} // initGuiPluginsByPriority
static void deleteGuiPlugin(PluginList *plugin)
{
if (plugin != NULL)
{
if (plugin->gui)
plugin->gui->deinit();
if (plugin->lib)
MojoPlatform_dlclose(plugin->lib);
free(plugin);
} // if
} // deleteGuiPlugin
static boolean tryGuiPlugin(PluginList *plugins, MojoGuiEntryPoint entry)
{
boolean retval = false;
const MojoGui *gui = entry(MOJOGUI_INTERFACE_REVISION, &GEntryPoints);
if (gui != NULL)
{
PluginList *plug = xmalloc(sizeof (PluginList));
plug->lib = NULL;
plug->gui = gui;
plug->priority = calcGuiPriority(gui);
plug->next = plugins->next;
plugins->next = plug;
retval = true;
} // if
return retval;
} // tryGuiPlugin
static void loadStaticGuiPlugins(PluginList *plugins)
{
int i;
for (i = 0; staticGui[i] != NULL; i++)
tryGuiPlugin(plugins, staticGui[i]);
} // loadStaticGuiPlugins
static boolean loadDynamicGuiPlugin(PluginList *plugins, MojoArchive *ar)
{
boolean rc = false;
void *lib = NULL;
MojoInput *io = ar->openCurrentEntry(ar);
if (io != NULL)
{
const uint32 imglen = (uint32) io->length(io);
uint8 *img = (uint8 *) xmalloc(imglen);
const uint32 br = (uint32) io->read(io, img, imglen);
io->close(io);
if (br == imglen)
lib = MojoPlatform_dlopen(img, imglen);
free(img);
} // if
if (lib != NULL)
{
void *addr = MojoPlatform_dlsym(lib, MOJOGUI_ENTRY_POINT_STR);
MojoGuiEntryPoint entry = (MojoGuiEntryPoint) addr;
if (entry != NULL)
{
if ((rc = tryGuiPlugin(plugins, entry)) == false)
MojoPlatform_dlclose(lib);
} // if
} // if
return rc;
} // loadDynamicGuiPlugin
static void loadDynamicGuiPlugins(PluginList *plugins)
{
if (GBaseArchive->enumerate(GBaseArchive))
{
const MojoArchiveEntry *entinfo;
while ((entinfo = GBaseArchive->enumNext(GBaseArchive)) != NULL)
{
if (entinfo->type != MOJOARCHIVE_ENTRY_FILE)
continue;
if (strncmp(entinfo->filename, "guis/", 5) != 0)
continue;
loadDynamicGuiPlugin(plugins, GBaseArchive);
} // while
} // if
} // loadDynamicGuiPlugins
const MojoGui *MojoGui_initGuiPlugin(void)
{
PluginList plugins;
PluginList *i = NULL;
if (pluginDetails != NULL)
return pluginDetails->gui;
memset(&plugins, '\0', sizeof (plugins));
assert(GGui == NULL);
loadDynamicGuiPlugins(&plugins);
loadStaticGuiPlugins(&plugins);
pluginDetails = initGuiPluginsByPriority(&plugins);
// cleanout unused plugins...
i = plugins.next;
while (i != NULL)
{
PluginList *next = i->next;
if (i != pluginDetails)
deleteGuiPlugin(i);
i = next;
} // while
if (pluginDetails != NULL)
{
GGui = pluginDetails->gui;
pluginDetails->next = NULL;
} // if
return GGui;
} // MojoGui_findGuiPlugin
void MojoGui_deinitGuiPlugin(void)
{
GGui = NULL;
deleteGuiPlugin(pluginDetails);
pluginDetails = NULL;
} // MojoGui_deinitGuiPlugin
// end of gui.c ...

View File

@@ -1,325 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*
*/
#ifndef _INCL_GUI_H_
#define _INCL_GUI_H_
#include "universal.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
MOJOGUI_PRIORITY_NEVER_TRY = 0,
MOJOGUI_PRIORITY_USER_REQUESTED,
MOJOGUI_PRIORITY_TRY_FIRST,
MOJOGUI_PRIORITY_TRY_NORMAL,
MOJOGUI_PRIORITY_TRY_LAST,
MOJOGUI_PRIORITY_TRY_ABSOLUTELY_LAST,
MOJOGUI_PRIORITY_TOTAL
} MojoGuiPluginPriority;
typedef enum
{
MOJOGUI_NO,
MOJOGUI_YES,
MOJOGUI_ALWAYS,
MOJOGUI_NEVER
} MojoGuiYNAN;
/*
* Abstract GUI interfaces.
*/
typedef struct MojoGuiSetupOptions MojoGuiSetupOptions;
struct MojoGuiSetupOptions
{
const char *description;
const char *tooltip;
boolean value;
boolean is_group_parent;
uint64 size;
int opaque; // GUI drivers shouldn't touch this.
void *guiopaque; // For GUI drivers. App won't touch or free this.
MojoGuiSetupOptions *next_sibling;
MojoGuiSetupOptions *child;
};
typedef enum
{
MOJOGUI_SPLASH_NONE,
MOJOGUI_SPLASH_TOP,
MOJOGUI_SPLASH_LEFT,
MOJOGUI_SPLASH_RIGHT,
MOJOGUI_SPLASH_BOTTOM,
MOJOGUI_SPLASH_BACKGROUND,
} MojoGuiSplashPos;
typedef struct MojoGuiSplash MojoGuiSplash;
struct MojoGuiSplash
{
const uint8 *rgba; // framebuffer.
uint32 w; // width in pixels.
uint32 h; // height in pixels.
MojoGuiSplashPos position; // where to put the splash.
};
#define MOJOGUI_ENTRY_POINT MojoSetup_Gui_GetInterface
#define MOJOGUI_ENTRY_POINT_STR DEFINE_TO_STR(MOJOGUI_ENTRY_POINT)
// Increment this value when MojoGui's structure changes.
#define MOJOGUI_INTERFACE_REVISION 6
typedef struct MojoGui MojoGui;
struct MojoGui
{
uint8 (*priority)(boolean istty);
const char* (*name)(void);
boolean (*init)(void);
void (*deinit)(void);
void (*msgbox)(const char *title, const char *text);
boolean (*promptyn)(const char *title, const char *text, boolean def);
MojoGuiYNAN (*promptynan)(const char *title, const char *text, boolean def);
boolean (*start)(const char *title, const MojoGuiSplash *splash);
void (*stop)(void);
int (*readme)(const char *name, const uint8 *data, size_t len,
boolean can_back, boolean can_fwd);
int (*options)(MojoGuiSetupOptions *opts,
boolean can_back, boolean can_fwd);
char * (*destination)(const char **recommendations, int recnum,
int *command, boolean can_back, boolean can_fwd);
int (*productkey)(const char *desc, const char *fmt, char *buf,
const int buflen, boolean can_back, boolean can_fwd);
boolean (*insertmedia)(const char *medianame);
void (*progressitem)(void);
boolean (*progress)(const char *type, const char *component,
int percent, const char *item, boolean can_cancel);
void (*final)(const char *msg);
};
typedef const MojoGui* (*MojoGuiEntryPoint)(int revision,
const MojoSetupEntryPoints *e);
#if !BUILDING_EXTERNAL_PLUGIN
extern const MojoGui *GGui;
const MojoGui *MojoGui_initGuiPlugin(void);
void MojoGui_deinitGuiPlugin(void);
#else
__EXPORT__ const MojoGui *MOJOGUI_ENTRY_POINT(int revision,
const MojoSetupEntryPoints *e);
/*
* We do this as a macro so we only have to update one place, and it
* enforces some details in the plugins. Without effort, plugins don't
* support anything but the latest version of the interface.
*/
#define MOJOGUI_PLUGIN(module) \
static const MojoSetupEntryPoints *entry = NULL; \
static uint8 MojoGui_##module##_priority(boolean istty); \
static const char* MojoGui_##module##_name(void) { return #module; } \
static boolean MojoGui_##module##_init(void); \
static void MojoGui_##module##_deinit(void); \
static void MojoGui_##module##_msgbox(const char *title, const char *text); \
static boolean MojoGui_##module##_promptyn(const char *t1, const char *t2, \
boolean d); \
static MojoGuiYNAN MojoGui_##module##_promptynan(const char *t1, \
const char *t2, boolean d); \
static boolean MojoGui_##module##_start(const char *t, \
const MojoGuiSplash *splash); \
static void MojoGui_##module##_stop(void); \
static int MojoGui_##module##_readme(const char *name, const uint8 *data, \
size_t len, boolean can_back, \
boolean can_fwd); \
static int MojoGui_##module##_options(MojoGuiSetupOptions *opts, \
boolean can_back, boolean can_fwd); \
static char *MojoGui_##module##_destination(const char **r, int recnum, \
int *command, boolean can_back, boolean can_fwd); \
static int MojoGui_##module##_productkey(const char *desc, const char *fmt, \
char *buf, const int buflen, boolean can_back, \
boolean can_fwd); \
static boolean MojoGui_##module##_insertmedia(const char *medianame); \
static void MojoGui_##module##_progressitem(void); \
static boolean MojoGui_##module##_progress(const char *typ, const char *comp, \
int percent, const char *item, \
boolean can_cancel); \
static void MojoGui_##module##_final(const char *msg); \
const MojoGui *MojoGuiPlugin_##module(int rev, const MojoSetupEntryPoints *e) \
{ \
if (rev == MOJOGUI_INTERFACE_REVISION) { \
static const MojoGui retval = { \
MojoGui_##module##_priority, \
MojoGui_##module##_name, \
MojoGui_##module##_init, \
MojoGui_##module##_deinit, \
MojoGui_##module##_msgbox, \
MojoGui_##module##_promptyn, \
MojoGui_##module##_promptynan, \
MojoGui_##module##_start, \
MojoGui_##module##_stop, \
MojoGui_##module##_readme, \
MojoGui_##module##_options, \
MojoGui_##module##_destination, \
MojoGui_##module##_productkey, \
MojoGui_##module##_insertmedia, \
MojoGui_##module##_progressitem, \
MojoGui_##module##_progress, \
MojoGui_##module##_final, \
}; \
entry = e; \
return &retval; \
} \
return NULL; \
} \
#define CREATE_MOJOGUI_ENTRY_POINT(module) \
const MojoGui *MOJOGUI_ENTRY_POINT(int rev, const MojoSetupEntryPoints *e) \
{ \
return MojoGuiPlugin_##module(rev, e); \
} \
// Redefine things that need to go through the plugin entry point interface,
// so plugins calling into the MojoSetup core can use the same code as the
// rest of the app.
#ifdef _
#undef _
#endif
#define _(x) entry->translate(x)
#ifdef xmalloc
#undef xmalloc
#endif
#define xmalloc(x) entry->xmalloc(x)
#ifdef xrealloc
#undef xrealloc
#endif
#define xrealloc(x,y) entry->xrealloc(x,y)
#ifdef xstrdup
#undef xstrdup
#endif
#define xstrdup(x) entry->xstrdup(x)
#ifdef xstrncpy
#undef xstrncpy
#endif
#define xstrncpy(x,y,z) entry->xstrcpy(x,y,z)
#ifdef logWarning
#undef logWarning
#endif
#define logWarning entry->logWarning
#ifdef logError
#undef logError
#endif
#define logError entry->logError
#ifdef logInfo
#undef logInfo
#endif
#define logInfo entry->logInfo
#ifdef logDebug
#undef logDebug
#endif
#define logDebug entry->logDebug
#ifdef format
#undef format
#endif
#define format entry->format
#ifdef numstr
#undef numstr
#endif
#define numstr(x) entry->numstr(x)
#ifdef ticks
#undef ticks
#endif
#define ticks() entry->ticks()
#ifdef utf8codepoint
#undef utf8codepoint
#endif
#define utf8codepoint(x) entry->utf8codepoint(x)
#ifdef utf8len
#undef utf8len
#endif
#define utf8len(x) entry->utf8len(x)
#ifdef splitText
#undef splitText
#endif
#define splitText(w,x,y,z) entry->splitText(w,x,y,z)
#ifdef isValidProductKey
#undef isValidProductKey
#endif
#define isValidProductKey(x,y) entry->isValidProductKey(x,y)
#endif
/*
* make some decisions about which GUI plugins to build...
* We list them all here, but some are built, some aren't. Some are DLLs,
* some aren't...
*/
const MojoGui *MojoGuiPlugin_stdio(int rev, const MojoSetupEntryPoints *e);
const MojoGui *MojoGuiPlugin_ncurses(int rev, const MojoSetupEntryPoints *e);
const MojoGui *MojoGuiPlugin_gtkplus2(int rev, const MojoSetupEntryPoints *e);
const MojoGui *MojoGuiPlugin_www(int rev, const MojoSetupEntryPoints *e);
const MojoGui *MojoGuiPlugin_cocoa(int rev, const MojoSetupEntryPoints *e);
// !!! FIXME: Qt? KDE? Gnome? Console? wxWidgets?
#ifdef __cplusplus
}
#endif
#endif
// end of gui.h ...

View File

@@ -1,822 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
Copyright (c) 2006-2010 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>
*/
#if !SUPPORT_GUI_COCOA
#error Something is wrong in the build system.
#endif
#import <Cocoa/Cocoa.h>
#undef true
#undef false
#define BUILDING_EXTERNAL_PLUGIN 1
#include "gui.h"
MOJOGUI_PLUGIN(cocoa)
#if !GUI_STATIC_LINK_COCOA
CREATE_MOJOGUI_ENTRY_POINT(cocoa)
#endif
typedef enum
{
CLICK_BACK=-1,
CLICK_CANCEL,
CLICK_NEXT,
CLICK_NONE
} ClickValue;
// This nasty hack is because we appear to need to be under
// -[NSApp run] when calling things like NSRunAlertPanel().
// So we push a custom event, call -[NSApp run], catch it, do
// the panel, then call -[NSApp stop]. Yuck.
typedef enum
{
CUSTOMEVENT_BASEVALUE=3234,
CUSTOMEVENT_RUNQUEUE,
CUSTOMEVENT_MSGBOX,
CUSTOMEVENT_PROMPTYN,
CUSTOMEVENT_PROMPTYNAN,
CUSTOMEVENT_INSERTMEDIA,
} CustomEvent;
static NSAutoreleasePool *GAutoreleasePool = nil;
@interface MojoSetupController : NSView
{
IBOutlet NSButton *BackButton;
IBOutlet NSButton *CancelButton;
IBOutlet NSComboBox *DestinationCombo;
IBOutlet NSTextField *FinalText;
IBOutlet NSWindow *MainWindow;
IBOutlet NSButton *NextButton;
IBOutlet NSProgressIndicator *ProgressBar;
IBOutlet NSTextField *ProgressComponentLabel;
IBOutlet NSTextField *ProgressItemLabel;
IBOutlet NSTextView *ReadmeText;
IBOutlet NSTabView *TabView;
IBOutlet NSTextField *TitleLabel;
IBOutlet NSMenuItem *QuitMenuItem;
IBOutlet NSMenuItem *AboutMenuItem;
IBOutlet NSMenuItem *HideMenuItem;
IBOutlet NSMenuItem *WindowMenuItem;
IBOutlet NSMenuItem *HideOthersMenuItem;
IBOutlet NSMenuItem *ShowAllMenuItem;
IBOutlet NSMenuItem *ServicesMenuItem;
IBOutlet NSMenuItem *MinimizeMenuItem;
IBOutlet NSMenuItem *ZoomMenuItem;
IBOutlet NSMenuItem *BringAllToFrontMenuItem;
IBOutlet NSView *OptionsView;
ClickValue clickValue;
boolean canForward;
boolean needToBreakEventLoop;
boolean finalPage;
MojoGuiYNAN answerYNAN;
MojoGuiSetupOptions *mojoOpts;
}
- (void)awakeFromNib;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
- (void)prepareWidgets:(const char*)winTitle;
- (void)unprepareWidgets;
- (void)fireCustomEvent:(CustomEvent)eventType data1:(NSInteger)data1 data2:(NSInteger)data2 atStart:(BOOL)atStart;
- (void)doCustomEvent:(NSEvent *)event;
- (void)doMsgBox:(const char *)title text:(const char *)text;
- (void)doPromptYN:(const char *)title text:(const char *)text;
- (void)doPromptYNAN:(const char *)title text:(const char *)text;
- (void)doInsertMedia:(const char *)medianame;
- (MojoGuiYNAN)getAnswerYNAN;
- (IBAction)backClicked:(NSButton *)sender;
- (IBAction)cancelClicked:(NSButton *)sender;
- (IBAction)nextClicked:(NSButton *)sender;
- (IBAction)browseClicked:(NSButton *)sender;
- (IBAction)menuQuit:(NSMenuItem *)sender;
- (int)doPage:(NSString *)pageId title:(const char *)_title canBack:(boolean)canBack canFwd:(boolean)canFwd canCancel:(boolean)canCancel canFwdAtStart:(boolean)canFwdAtStart shouldBlock:(BOOL)shouldBlock;
- (int)doReadme:(const char *)title text:(NSString *)text canBack:(boolean)canBack canFwd:(boolean)canFwd;
- (void)setOptionTreeSensitivity:(MojoGuiSetupOptions *)opts enabled:(boolean)val;
- (void)optionToggled:(id)toggle;
- (NSView *)newOptionLevel:(NSView *)box;
- (void)buildOptions:(MojoGuiSetupOptions *)opts view:(NSView *)box sensitive:(boolean)sensitive;
- (int)doOptions:(MojoGuiSetupOptions *)opts canBack:(boolean)canBack canFwd:(boolean)canFwd;
- (char *)doDestination:(const char **)recommends recnum:(int)recnum command:(int *)command canBack:(boolean)canBack canFwd:(boolean)canFwd;
- (int)doProductKey:(const char *)desc fmt:(const char *)fmt buf:(char *)buf buflen:(const int)buflen canBack:(boolean)canBack canFwd:(boolean)canFwd;
- (int)doProgress:(const char *)type component:(const char *)component percent:(int)percent item:(const char *)item canCancel:(boolean)canCancel;
- (void)doFinal:(const char *)msg;
@end // interface MojoSetupController
@implementation MojoSetupController
- (void)awakeFromNib
{
clickValue = CLICK_NONE;
canForward = false;
answerYNAN = MOJOGUI_NO;
needToBreakEventLoop = false;
finalPage = false;
mojoOpts = nil;
} // awakeFromNib
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
printf("didfinishlaunching\n");
[NSApp stop:self]; // break out of NSApp::run()
} // applicationDidFinishLaunching
- (void)prepareWidgets:(const char*)winTitle
{
#if 1
[BackButton setTitle:[NSString stringWithUTF8String:_("Back")]];
[NextButton setTitle:[NSString stringWithUTF8String:_("Next")]];
[CancelButton setTitle:[NSString stringWithUTF8String:_("Cancel")]];
#else
// !!! FIXME: there's probably a better way to do this.
// Set the correct localization for the buttons, then resize them so
// the new text fits perfectly. After that, we need to reposition
// them so they don't look scattered.
NSRect frameBack = [BackButton frame];
NSRect frameNext = [NextButton frame];
NSRect frameCancel = [CancelButton frame];
const float startX = frameCancel.origin.x + frameCancel.size.width;
const float spacing = (frameBack.origin.x + frameBack.size.width) - frameNext.origin.x;
[BackButton setTitle:[NSString stringWithUTF8String:_("Back")]];
[NextButton setTitle:[NSString stringWithUTF8String:_("Next")]];
[CancelButton setTitle:[NSString stringWithUTF8String:_("Cancel")]];
[BackButton sizeToFit];
[NextButton sizeToFit];
[CancelButton sizeToFit];
frameBack = [BackButton frame];
frameNext = [NextButton frame];
frameCancel = [CancelButton frame];
frameCancel.origin.x = startX - frameCancel.size.width;
frameNext.origin.x = (frameCancel.origin.x - frameNext.size.width) - spacing;
frameBack.origin.x = (frameNext.origin.x - frameBack.size.width) - spacing;
[CancelButton setFrame:frameCancel];
[CancelButton setNeedsDisplay:YES];
[NextButton setFrame:frameNext];
[NextButton setNeedsDisplay:YES];
[BackButton setFrame:frameBack];
[BackButton setNeedsDisplay:YES];
#endif
[ProgressBar setUsesThreadedAnimation:YES]; // we don't pump fast enough.
[ProgressBar startAnimation:self];
[WindowMenuItem setTitle:[NSString stringWithUTF8String:_("Window")]];
[HideOthersMenuItem setTitle:[NSString stringWithUTF8String:_("Hide Others")]];
[ShowAllMenuItem setTitle:[NSString stringWithUTF8String:_("Show All")]];
[ServicesMenuItem setTitle:[NSString stringWithUTF8String:_("Services")]];
[MinimizeMenuItem setTitle:[NSString stringWithUTF8String:_("Minimize")]];
[ZoomMenuItem setTitle:[NSString stringWithUTF8String:_("Zoom")]];
[BringAllToFrontMenuItem setTitle:[NSString stringWithUTF8String:_("Bring All to Front")]];
NSString *appName;
appName = (NSString *) [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
if (appName == nil)
appName = [[NSProcessInfo processInfo] processName];
const char *utf8AppName = [appName UTF8String];
char *text;
text = format(_("About %0"), utf8AppName);
[AboutMenuItem setTitle:[NSString stringWithUTF8String:text]];
free(text);
text = format(_("Hide %0"), utf8AppName);
[HideMenuItem setTitle:[NSString stringWithUTF8String:text]];
free(text);
text = format(_("Quit %0"), utf8AppName);
[QuitMenuItem setTitle:[NSString stringWithUTF8String:text]];
free(text);
[MainWindow setTitle:[NSString stringWithUTF8String:winTitle]];
[MainWindow center];
[MainWindow makeKeyAndOrderFront:self];
} // prepareWidgets
- (void)unprepareWidgets
{
[MainWindow orderOut:self];
} // unprepareWidgets
- (void)fireCustomEvent:(CustomEvent)eventType data1:(NSInteger)data1 data2:(NSInteger)data2 atStart:(BOOL)atStart
{
NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:0 windowNumber:0 context:nil subtype:(short)eventType data1:data1 data2:data2];
[NSApp postEvent:event atStart:atStart];
[NSApp run]; // event handler _must_ call -[NSApp stop], or you block here forever.
} // fireCustomEvent
- (void)doCustomEvent:(NSEvent*)event
{
printf("custom event!\n");
switch ((CustomEvent) [event subtype])
{
case CUSTOMEVENT_RUNQUEUE:
if ([NSApp modalWindow] != nil)
{
// If we're in a modal thing, so don't break the event loop.
// Just make a note to break it later.
needToBreakEventLoop = true;
return;
} // if
break; // we just need the -[NSApp stop] call.
case CUSTOMEVENT_MSGBOX:
[self doMsgBox:(const char *)[event data1] text:(const char *)[event data2]];
break;
case CUSTOMEVENT_PROMPTYN:
[self doPromptYN:(const char *)[event data1] text:(const char *)[event data2]];
break;
case CUSTOMEVENT_PROMPTYNAN:
[self doPromptYNAN:(const char *)[event data1] text:(const char *)[event data2]];
break;
case CUSTOMEVENT_INSERTMEDIA:
[self doInsertMedia:(const char *)[event data1]];
break;
default:
return; // let it go without breaking the event loop.
} // switch
[NSApp stop:self]; // break the event loop.
} // doCustomEvent
- (void)doMsgBox:(const char *)title text:(const char *)text
{
NSString *titlestr = [NSString stringWithUTF8String:title];
NSString *textstr = [NSString stringWithUTF8String:text];
NSString *okstr = [NSString stringWithUTF8String:_("OK")];
NSRunInformationalAlertPanel(titlestr, textstr, okstr, nil, nil);
if (needToBreakEventLoop)
{
needToBreakEventLoop = false;
[self fireCustomEvent:CUSTOMEVENT_RUNQUEUE data1:0 data2:0 atStart:NO];
} // if
} // doMsgBox
- (void)doPromptYN:(const char *)title text:(const char *)text
{
NSString *titlestr = [NSString stringWithUTF8String:title];
NSString *textstr = [NSString stringWithUTF8String:text];
NSString *yesstr = [NSString stringWithUTF8String:_("Yes")];
NSString *nostr = [NSString stringWithUTF8String:_("No")];
const NSInteger rc = NSRunAlertPanel(titlestr, textstr, yesstr, nostr, nil);
answerYNAN = ((rc == NSAlertDefaultReturn) ? MOJOGUI_YES : MOJOGUI_NO);
if (needToBreakEventLoop)
{
needToBreakEventLoop = false;
[self fireCustomEvent:CUSTOMEVENT_RUNQUEUE data1:0 data2:0 atStart:NO];
} // if
} // doPromptYN
- (void)doPromptYNAN:(const char *)title text:(const char *)text
{
// !!! FIXME
[self doPromptYN:title text:text];
} // doPromptYN
- (void)doInsertMedia:(const char *)medianame
{
NSString *title = [NSString stringWithUTF8String:_("Media change")];
char *fmt = xstrdup(_("Please insert '%0'"));
char *_text = format(fmt, medianame);
NSString *text = [NSString stringWithUTF8String:_text];
free(_text);
free(fmt);
NSString *okstr = [NSString stringWithUTF8String:_("OK")];
NSString *cancelstr = [NSString stringWithUTF8String:_("Cancel")];
const NSInteger rc = NSRunAlertPanel(title, text, okstr, cancelstr, nil);
answerYNAN = ((rc == NSAlertDefaultReturn) ? MOJOGUI_YES : MOJOGUI_NO);
if (needToBreakEventLoop)
{
needToBreakEventLoop = false;
[self fireCustomEvent:CUSTOMEVENT_RUNQUEUE data1:0 data2:0 atStart:NO];
} // if
} // doInsertMedia
- (MojoGuiYNAN)getAnswerYNAN
{
return answerYNAN;
} // getAnswerYNAN
- (IBAction)backClicked:(NSButton *)sender
{
clickValue = CLICK_BACK;
[NSApp stop:self];
} // backClicked
- (IBAction)cancelClicked:(NSButton *)sender
{
char *title = xstrdup(_("Cancel installation"));
char *text = xstrdup(_("Are you sure you want to cancel installation?"));
[self doPromptYN:title text:text];
free(title);
free(text);
if (answerYNAN == MOJOGUI_YES)
{
clickValue = CLICK_CANCEL;
[NSApp stop:self];
} // if
} // cancelClicked
- (IBAction)nextClicked:(NSButton *)sender
{
clickValue = CLICK_NEXT;
[NSApp stop:self];
} // nextClicked
- (IBAction)browseClicked:(NSButton *)sender
{
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setTitle:[NSString stringWithUTF8String:_("Destination")]];
[panel setAllowsMultipleSelection:NO];
[panel setCanCreateDirectories:YES];
[panel setCanChooseDirectories:YES];
[panel setCanChooseFiles:NO];
if ([panel runModal] == NSOKButton)
[DestinationCombo setStringValue:[panel filename]];
} // browseClicked
- (IBAction)menuQuit:(NSMenuItem *)sender
{
if (finalPage) // make this work like you clicked "finished".
[self nextClicked:nil];
else if ([CancelButton isEnabled]) // make this work like you clicked "cancel".
[self cancelClicked:nil];
} // menuQuit
- (int)doPage:(NSString *)pageId title:(const char *)_title canBack:(boolean)canBack canFwd:(boolean)canFwd canCancel:(boolean)canCancel canFwdAtStart:(boolean)canFwdAtStart shouldBlock:(BOOL)shouldBlock
{
[TitleLabel setStringValue:[NSString stringWithUTF8String:_title]];
clickValue = CLICK_NONE;
canForward = canFwd;
[BackButton setEnabled:canBack ? YES : NO];
[NextButton setEnabled:canFwdAtStart ? YES : NO];
[CancelButton setEnabled:canCancel ? YES : NO];
[TabView selectTabViewItemWithIdentifier:pageId];
if (shouldBlock == NO)
[self fireCustomEvent:CUSTOMEVENT_RUNQUEUE data1:0 data2:0 atStart:NO];
else
{
[NSApp run];
assert(clickValue < CLICK_NONE);
} // else
return (int) clickValue;
} // doPage
- (int)doReadme:(const char *)title text:(NSString *)text canBack:(boolean)canBack canFwd:(boolean)canFwd
{
NSRange range = {0, 1}; // reset scrolling to start of text.
[ReadmeText setString:text];
[ReadmeText scrollRangeToVisible:range];
return [self doPage:@"Readme" title:title canBack:canBack canFwd:canFwd canCancel:true canFwdAtStart:canFwd shouldBlock:YES];
} // doReadme
- (void)setOptionTreeSensitivity:(MojoGuiSetupOptions *)opts enabled:(boolean)val
{
if (opts != nil)
{
[((id) opts->guiopaque) setEnabled:(val ? YES : NO)];
[self setOptionTreeSensitivity:opts->next_sibling enabled:val];
[self setOptionTreeSensitivity:opts->child enabled:(val && opts->value)];
} // if
} // setOptionTreeSensitivity
- (MojoGuiSetupOptions *)findMojoOption:(id)obj opt:(MojoGuiSetupOptions *)opt
{
// !!! FIXME: this is not ideal. How can we attach this pointer to
// !!! FIXME: the objects themselves so we don't have to walk a tree
// !!! FIXME: to find it on each action? The objects are controls
// !!! FIXME: and cells (distinct classes), and I don't control the
// !!! FIXME: creation of all of them (radio buttons).
// !!! FIXME: Alternately, let's just hold a hashtable to map
// !!! FIXME: objects to options without walking this tree.
if (opt == nil)
return nil;
MojoGuiSetupOptions *i;
for (i = opt; i != nil; i = i->next_sibling)
{
if (i->guiopaque == ((void *) obj))
return i;
MojoGuiSetupOptions *rc = [self findMojoOption:obj opt:i->child];
if (rc != nil)
return rc;
} // for
return [self findMojoOption:obj opt:opt->child];
} // findMojoOption
- (void)optionToggled:(id)toggle
{
MojoGuiSetupOptions *opts = [self findMojoOption:toggle opt:mojoOpts];
assert(opts != nil);
// !!! FIXME: cast is wrong. use a selector?
const boolean enabled = ([((NSControl*)toggle) isEnabled] == YES);
opts->value = enabled;
[self setOptionTreeSensitivity:opts->child enabled:enabled];
} // optionToggled
- (NSView *)newOptionLevel:(NSView *)box
{
NSRect frame = NSMakeRect(10, 10, 10, 10);
NSView *widget = [[NSView alloc] initWithFrame:frame];
[box addSubview:widget positioned:NSWindowBelow relativeTo:nil];
[widget release]; // (box) owns it now.
return widget;
} // newOptionLevel
// !!! FIXME: most of this mess is cut, pasted, and Cocoaized from the
// !!! FIXME: GTK+ GUI. Can we abstract this in the high level and just
// !!! FIXME: implement the target-specific bits in the plugins?
- (void)buildOptions:(MojoGuiSetupOptions *)opts view:(NSView *)box sensitive:(boolean)sensitive
{
NSRect frame = NSMakeRect(10, 10, 10, 10);
if (opts != nil)
{
if (opts->is_group_parent)
{
MojoGuiSetupOptions *kids = opts->child;
NSView *childbox = nil;
//GtkWidget *alignment = gtk_alignment_new(0.0, 0.5, 0, 0);
//gtk_widget_show(alignment);
// !!! FIXME: disable line wrap?
// !!! FIXME: resize on superview resize?
NSTextField *widget = [[NSTextField alloc] initWithFrame:frame];
[widget setStringValue:[NSString stringWithUTF8String:opts->description]];
[widget setEnabled:(sensitive ? YES : NO)];
[widget setEditable:NO];
[widget setSelectable:NO];
[widget setBordered:NO];
[widget setBezeled:NO];
[widget setAlignment:NSLeftTextAlignment];
[widget sizeToFit];
if (opts->tooltip != nil)
[widget setToolTip:[NSString stringWithUTF8String:opts->tooltip]];
[box addSubview:widget positioned:NSWindowBelow relativeTo:nil];
[widget release]; // (box) owns it now.
//!!! FIXME[box sizeToFit];
childbox = [self newOptionLevel:box];
NSButtonCell *prototype = [[NSButtonCell alloc] init];
[prototype setButtonType:NSRadioButton];
[prototype setAllowsMixedState:NO];
NSMatrix *matrix = [[NSMatrix alloc] initWithFrame:frame mode:NSRadioModeMatrix prototype:(NSCell *)prototype numberOfRows:0 numberOfColumns:1];
int row = 0;
while (kids)
{
[matrix addRow];
NSButtonCell *cell = (NSButtonCell *) [matrix cellAtRow:row column:0];
kids->guiopaque = cell;
[cell setTitle:[NSString stringWithUTF8String:kids->description]];
[matrix setState:(kids->value ? NSOnState : NSOffState) atRow:row column:0];
[cell setEnabled:(kids->value ? YES : NO)];
[cell setTarget:self];
[cell setAction:@selector(optionToggled:)];
if (kids->tooltip != nil)
[matrix setToolTip:[NSString stringWithUTF8String:kids->tooltip] forCell:cell];
if (kids->child != nil)
[self buildOptions:kids->child view:[self newOptionLevel:childbox] sensitive:sensitive];
kids = kids->next_sibling;
row++;
} // while
[matrix sizeToCells];
[childbox addSubview:matrix positioned:NSWindowBelow relativeTo:nil];
[matrix release]; // childbox owns it now.
//!!! FIXME: [childbox sizeToFit];
//!!! FIXME: [[childbox superview] sizeToFit];
} // if
else
{
NSButton *widget = [[NSButton alloc] initWithFrame:frame];
opts->guiopaque = widget;
[widget setAllowsMixedState:NO];
[widget setTitle:[NSString stringWithUTF8String:opts->description]];
[widget setState:(opts->value ? NSOnState : NSOffState)];
[widget setEnabled:(sensitive ? YES : NO)];
[widget setTarget:self];
[widget setAction:@selector(optionToggled:)];
[box addSubview:widget positioned:NSWindowBelow relativeTo:nil];
[widget release]; // (box) owns it now.
//!!!FIXME:[box sizeToFit];
if (opts->tooltip != nil)
[widget setToolTip:[NSString stringWithUTF8String:opts->tooltip]];
if (opts->child != nil)
[self buildOptions:opts->child view:[self newOptionLevel:box] sensitive:((sensitive) && (opts->value))];
} // else
[self buildOptions:opts->next_sibling view:box sensitive:sensitive];
} // if
//!!! FIXME:[box sizeToFit];
} // buildOptions
- (int)doOptions:(MojoGuiSetupOptions *)opts canBack:(boolean)canBack canFwd:(boolean)canFwd
{
// add all the option widgets to the page's view.
[self buildOptions:opts view:OptionsView sensitive:true];
// run the page.
mojoOpts = opts;
int retval = [self doPage:@"Options" title:_("Options") canBack:canBack canFwd:canFwd canCancel:true canFwdAtStart:canFwd shouldBlock:YES];
mojoOpts = nil;
// we're done, so nuke everything from the view.
NSArray *array = [[OptionsView subviews] copy];
NSEnumerator *enumerator = [array objectEnumerator];
NSView *obj;
while ((obj = (NSView *) [enumerator nextObject]) != nil)
[obj removeFromSuperviewWithoutNeedingDisplay];
[OptionsView setNeedsDisplay:YES];
[enumerator release];
[array release];
return retval;
} // doOptions
- (char *)doDestination:(const char **)recommends recnum:(int)recnum command:(int *)command canBack:(boolean)canBack canFwd:(boolean)canFwd
{
const boolean fwdAtStart = ( (recnum > 0) && (*(recommends[0])) );
int i;
[DestinationCombo removeAllItems];
for (i = 0; i < recnum; i++)
[DestinationCombo addItemWithObjectValue:[NSString stringWithUTF8String:recommends[i]]];
if (recnum > 0)
[DestinationCombo setStringValue:[NSString stringWithUTF8String:recommends[0]]];
else
[DestinationCombo setStringValue:@""];
*command = [self doPage:@"Destination" title:_("Destination") canBack:canBack canFwd:canFwd canCancel:true canFwdAtStart:fwdAtStart shouldBlock:YES];
char *retval = xstrdup([[DestinationCombo stringValue] UTF8String]);
[DestinationCombo removeAllItems];
[DestinationCombo setStringValue:@""];
return retval;
} // doDestination
- (int)doProductKey:(const char *)desc fmt:(const char *)fmt buf:(char *)buf buflen:(const int)buflen canBack:(boolean)canBack canFwd:(boolean)canFwd
{
// !!! FIXME: write me!
return [self doPage:@"ProductKey" title:desc canBack:canBack canFwd:canFwd canCancel:true canFwdAtStart:canFwd shouldBlock:YES];
} // doProductKey
- (int)doProgress:(const char *)type component:(const char *)component percent:(int)percent item:(const char *)item canCancel:(boolean)canCancel
{
const BOOL indeterminate = (percent < 0) ? YES : NO;
[ProgressComponentLabel setStringValue:[NSString stringWithUTF8String:component]];
[ProgressItemLabel setStringValue:[NSString stringWithUTF8String:item]];
[ProgressBar setIndeterminate:indeterminate];
if (!indeterminate)
[ProgressBar setDoubleValue:(double)percent];
return [self doPage:@"Progress" title:type canBack:false canFwd:false canCancel:canCancel canFwdAtStart:false shouldBlock:NO];
} // doProgress
- (void)doFinal:(const char *)msg
{
finalPage = true;
[FinalText setStringValue:[NSString stringWithUTF8String:msg]];
[NextButton setTitle:[NSString stringWithUTF8String:_("Finish")]];
[self doPage:@"Final" title:_("Finish") canBack:false canFwd:true canCancel:false canFwdAtStart:true shouldBlock:YES];
} // doFinal
@end // implementation MojoSetupController
// Override [NSApplication sendEvent], so we can catch custom events.
@interface MojoSetupApplication : NSApplication
{
}
- (void)sendEvent:(NSEvent *)event;
@end // interface MojoSetupApplication
@implementation MojoSetupApplication
- (void)sendEvent:(NSEvent *)event
{
if ([event type] == NSApplicationDefined)
[((MojoSetupController *)[self delegate]) doCustomEvent:event];
[super sendEvent:event];
} // sendEvent
@end // implementation MojoSetupApplication
static uint8 MojoGui_cocoa_priority(boolean istty)
{
// obviously this is the thing you want on Mac OS X.
return MOJOGUI_PRIORITY_TRY_FIRST;
} // MojoGui_cocoa_priority
static boolean MojoGui_cocoa_init(void)
{
// This lets a stdio app become a GUI app. Otherwise, you won't get
// GUI events from the system and other things will fail to work.
// Putting the app in an application bundle does the same thing.
// TransformProcessType() is a 10.3+ API. SetFrontProcess() is 10.0+.
if (TransformProcessType != NULL) // check it as a weak symbol.
{
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn);
} // if
GAutoreleasePool = [[NSAutoreleasePool alloc] init];
// !!! FIXME: make sure we have access to the desktop...may be ssh'd in
// !!! FIXME: as another user that doesn't have the Finder loaded or
// !!! FIXME: something.
// For NSApp to be our subclass, instead of default NSApplication.
[MojoSetupApplication sharedApplication];
if ([NSBundle loadNibNamed:@"MojoSetup" owner:NSApp] == NO)
return false;
// Force NSApp initialization stuff. MojoSetupController is set, in the
// .nib, to be NSApp's delegate. Its applicationDidFinishLaunching calls
// [NSApp stop] to break event loop right away so we can continue.
[NSApp run];
return true; // always succeeds.
} // MojoGui_cocoa_init
static void MojoGui_cocoa_deinit(void)
{
[GAutoreleasePool release];
GAutoreleasePool = nil;
// !!! FIXME: destroy nib and NSApp?
} // MojoGui_cocoa_deinit
static void MojoGui_cocoa_msgbox(const char *title, const char *text)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSApp delegate] fireCustomEvent:CUSTOMEVENT_MSGBOX data1:(NSInteger)title data2:(NSInteger)text atStart:YES];
[pool release];
} // MojoGui_cocoa_msgbox
static boolean MojoGui_cocoa_promptyn(const char *title, const char *text,
boolean defval)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSApp delegate] fireCustomEvent:CUSTOMEVENT_PROMPTYN data1:(NSInteger)title data2:(NSInteger)text atStart:YES];
const MojoGuiYNAN ynan = [[NSApp delegate] getAnswerYNAN];
[pool release];
assert((ynan == MOJOGUI_YES) || (ynan == MOJOGUI_NO));
return (ynan == MOJOGUI_YES);
} // MojoGui_cocoa_promptyn
static MojoGuiYNAN MojoGui_cocoa_promptynan(const char *title,
const char *text,
boolean defval)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSApp delegate] fireCustomEvent:CUSTOMEVENT_PROMPTYNAN data1:(NSInteger)title data2:(NSInteger)text atStart:YES];
const MojoGuiYNAN retval = [[NSApp delegate] getAnswerYNAN];
[pool release];
return retval;
} // MojoGui_cocoa_promptynan
static boolean MojoGui_cocoa_start(const char *title,
const MojoGuiSplash *splash)
{
printf("start\n");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// !!! FIXME: deal with (splash).
[[NSApp delegate] prepareWidgets:title];
[pool release];
return true;
} // MojoGui_cocoa_start
static void MojoGui_cocoa_stop(void)
{
printf("stop\n");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSApp delegate] unprepareWidgets];
[pool release];
} // MojoGui_cocoa_stop
static int MojoGui_cocoa_readme(const char *name, const uint8 *data,
size_t len, boolean can_back,
boolean can_fwd)
{
printf("readme\n");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *str = [[[NSString alloc] initWithBytes:data length:len encoding:NSUTF8StringEncoding] autorelease];
const int retval = [[NSApp delegate] doReadme:name text:str canBack:can_back canFwd:can_fwd];
[pool release];
return retval;
} // MojoGui_cocoa_readme
static int MojoGui_cocoa_options(MojoGuiSetupOptions *opts,
boolean can_back, boolean can_fwd)
{
printf("options\n");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
const int retval = [[NSApp delegate] doOptions:opts canBack:can_back canFwd:can_fwd];
[pool release];
return retval;
} // MojoGui_cocoa_options
static char *MojoGui_cocoa_destination(const char **recommends, int recnum,
int *command, boolean can_back,
boolean can_fwd)
{
printf("destination\n");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
char *retval = [[NSApp delegate] doDestination:recommends recnum:recnum command:command canBack:can_back canFwd:can_fwd];
[pool release];
return retval;
} // MojoGui_cocoa_destination
static int MojoGui_cocoa_productkey(const char *desc, const char *fmt,
char *buf, const int buflen,
boolean can_back, boolean can_fwd)
{
printf("productkey\n");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
const int retval = [[NSApp delegate] doProductKey:desc fmt:fmt buf:buf buflen:buflen canBack:can_back canFwd:can_fwd];
[pool release];
return retval;
} // MojoGui_cocoa_productkey
static boolean MojoGui_cocoa_insertmedia(const char *medianame)
{
printf("insertmedia\n");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSApp delegate] fireCustomEvent:CUSTOMEVENT_INSERTMEDIA data1:(NSInteger)medianame data2:0 atStart:YES];
const MojoGuiYNAN ynan = [[NSApp delegate] getAnswerYNAN];
assert((ynan == MOJOGUI_YES) || (ynan == MOJOGUI_NO));
[pool release];
return (ynan == MOJOGUI_YES);
} // MojoGui_cocoa_insertmedia
static void MojoGui_cocoa_progressitem(void)
{
printf("progressitem\n");
// no-op in this UI target.
} // MojoGui_cocoa_progressitem
static int MojoGui_cocoa_progress(const char *type, const char *component,
int percent, const char *item,
boolean can_cancel)
{
printf("progress\n");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
const int retval = [[NSApp delegate] doProgress:type component:component percent:percent item:item canCancel:can_cancel];
[pool release];
return retval;
} // MojoGui_cocoa_progress
static void MojoGui_cocoa_final(const char *msg)
{
printf("final\n");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[NSApp delegate] doFinal:msg];
[pool release];
} // MojoGui_cocoa_final
// end of gui_cocoa.m ...

View File

@@ -1,938 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*
*/
// Not only does GTK+ 2.x _look_ better than 1.x, it offers a lot of basic
// functionality, like message boxes, that you'd expect to exist in a GUI
// toolkit. In GTK+v1, you'd have to roll all that on your own!
//
// It's easier to implement in that regard, and produces a smaller DLL, but
// it has a million dependencies, so you might need to use a GTK+v1 plugin,
// too, in case they break backwards compatibility.
#if !SUPPORT_GUI_GTKPLUS2
#error Something is wrong in the build system.
#endif
#define BUILDING_EXTERNAL_PLUGIN 1
#include "gui.h"
MOJOGUI_PLUGIN(gtkplus2)
#if !GUI_STATIC_LINK_GTKPLUS2
CREATE_MOJOGUI_ENTRY_POINT(gtkplus2)
#endif
#undef format
#include <gtk/gtk.h>
#define format entry->format
typedef enum
{
PAGE_INTRO,
PAGE_README,
PAGE_OPTIONS,
PAGE_DEST,
PAGE_PRODUCTKEY,
PAGE_PROGRESS,
PAGE_FINAL
} WizardPages;
static WizardPages currentpage = PAGE_INTRO;
static gboolean canfwd = TRUE;
static GtkWidget *gtkwindow = NULL;
static GtkWidget *pagetitle = NULL;
static GtkWidget *notebook = NULL;
static GtkWidget *readme = NULL;
static GtkWidget *cancel = NULL;
static GtkWidget *back = NULL;
static GtkWidget *next = NULL;
static GtkWidget *finish = NULL;
static GtkWidget *msgbox = NULL;
static GtkWidget *destination = NULL;
static GtkWidget *productkey = NULL;
static GtkWidget *progressbar = NULL;
static GtkWidget *progresslabel = NULL;
static GtkWidget *finallabel = NULL;
static GtkWidget *browse = NULL;
static GtkWidget *splash = NULL;
static volatile enum
{
CLICK_BACK=-1,
CLICK_CANCEL,
CLICK_NEXT,
CLICK_NONE
} click_value = CLICK_NONE;
static void prepare_wizard(const char *name, WizardPages page,
boolean can_back, boolean can_fwd,
boolean can_cancel, boolean fwd_at_start)
{
char *markup = g_markup_printf_escaped(
"<span size='large' weight='bold'>%s</span>",
name);
currentpage = page;
canfwd = can_fwd;
gtk_label_set_markup(GTK_LABEL(pagetitle), markup);
g_free(markup);
gtk_widget_set_sensitive(back, can_back);
gtk_widget_set_sensitive(next, fwd_at_start);
gtk_widget_set_sensitive(cancel, can_cancel);
gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), (gint) page);
assert(click_value == CLICK_NONE);
assert(gtkwindow != NULL);
assert(msgbox == NULL);
} // prepare_wizard
static int wait_event(void)
{
int retval = 0;
// signals fired under gtk_main_iteration can change click_value.
gtk_main_iteration();
if (click_value == CLICK_CANCEL)
{
char *title = xstrdup(_("Cancel installation"));
char *text = xstrdup(_("Are you sure you want to cancel installation?"));
if (!MojoGui_gtkplus2_promptyn(title, text, false))
click_value = CLICK_NONE;
free(title);
free(text);
} // if
assert(click_value <= CLICK_NONE);
retval = (int) click_value;
click_value = CLICK_NONE;
return retval;
} // wait_event
static int pump_events(void)
{
int retval = (int) CLICK_NONE;
while ( (retval == ((int) CLICK_NONE)) && (gtk_events_pending()) )
retval = wait_event();
return retval;
} // pump_events
static int run_wizard(const char *name, WizardPages page,
boolean can_back, boolean can_fwd, boolean can_cancel,
boolean fwd_at_start)
{
int retval = CLICK_NONE;
prepare_wizard(name, page, can_back, can_fwd, can_cancel, fwd_at_start);
while (retval == ((int) CLICK_NONE))
retval = wait_event();
assert(retval < ((int) CLICK_NONE));
return retval;
} // run_wizard
static gboolean signal_delete(GtkWidget *w, GdkEvent *evt, gpointer data)
{
click_value = CLICK_CANCEL;
return TRUE; /* eat event: default handler destroys window! */
} // signal_delete
static void signal_clicked(GtkButton *_button, gpointer data)
{
GtkWidget *button = GTK_WIDGET(_button);
if (button == back)
click_value = CLICK_BACK;
else if (button == cancel)
click_value = CLICK_CANCEL;
else if ((button == next) || (button == finish))
click_value = CLICK_NEXT;
else
{
assert(0 && "Unknown click event.");
} // else
} // signal_clicked
static void signal_browse_clicked(GtkButton *_button, gpointer data)
{
GtkWidget *dialog = gtk_file_chooser_dialog_new (
_("Destination"),
NULL,
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
gtk_combo_box_get_active_text(GTK_COMBO_BOX(destination)));
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
gchar *filename;
gchar *utfname;
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
utfname = g_filename_to_utf8(filename, -1, NULL, NULL, NULL);
gtk_combo_box_prepend_text(GTK_COMBO_BOX(destination), utfname);
gtk_combo_box_set_active(GTK_COMBO_BOX(destination), 0);
g_free(utfname);
g_free(filename);
}
// !!! FIXME: should append the package name to the directory they chose?
// !!! FIXME: This is annoying, they might have created the folder
// !!! FIXME: themselves in the dialog.
// !!! FIXME: Could warn when the target directory already contains files?
gtk_widget_destroy(dialog);
} // signal_browse_clicked
static void signal_dest_changed(GtkComboBox *combo, gpointer user_data)
{
// Disable the forward button when the destination entry is blank.
if ((currentpage == PAGE_DEST) && (canfwd))
{
gchar *str = gtk_combo_box_get_active_text(combo);
const gboolean filled_in = ((str != NULL) && (*str != '\0'));
g_free(str);
gtk_widget_set_sensitive(next, filled_in);
} // if
} // signal_dest_changed
static void signal_productkey_changed(GtkEditable *edit, gpointer user_data)
{
// Disable the forward button when the entry is blank.
if ((currentpage == PAGE_PRODUCTKEY) && (canfwd))
{
const char *fmt = (const char *) user_data;
char *key = (char *) gtk_editable_get_chars(edit, 0, -1);
const gboolean okay = isValidProductKey(fmt, key);
g_free(key);
gtk_widget_set_sensitive(next, okay);
} // if
} // signal_productkey_changed
static uint8 MojoGui_gtkplus2_priority(boolean istty)
{
// gnome-session exports this environment variable since 2002.
if (getenv("GNOME_DESKTOP_SESSION_ID") != NULL)
return MOJOGUI_PRIORITY_TRY_FIRST;
return MOJOGUI_PRIORITY_TRY_NORMAL;
} // MojoGui_gtkplus2_priority
static boolean MojoGui_gtkplus2_init(void)
{
int tmpargc = 0;
char *args[] = { NULL, NULL };
char **tmpargv = args;
if (!gtk_init_check(&tmpargc, &tmpargv))
{
logInfo("gtkplus2: gtk_init_check() failed, use another UI.");
return false;
} // if
return true;
} // MojoGui_gtkplus2_init
static void MojoGui_gtkplus2_deinit(void)
{
// !!! FIXME: GTK+ doesn't have a deinit function...it installs a crappy
// !!! FIXME: atexit() function!
} // MojoGui_gtkplus2_deinit
/**
*
* @param defbutton The response ID to use when enter is pressed, or 0
* to leave it up to GTK+.
*/
static gint do_msgbox(const char *title, const char *text,
GtkMessageType mtype, GtkButtonsType btype,
GtkResponseType defbutton,
void (*addButtonCallback)(GtkWidget *_msgbox))
{
gint retval = 0;
// Modal dialog, this will never be called recursively.
assert(msgbox == NULL);
msgbox = gtk_message_dialog_new(GTK_WINDOW(gtkwindow), GTK_DIALOG_MODAL,
mtype, btype, "%s", title);
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(msgbox),
"%s", text);
if (defbutton)
gtk_dialog_set_default_response(GTK_DIALOG(msgbox), defbutton);
if (addButtonCallback != NULL)
addButtonCallback(msgbox);
retval = gtk_dialog_run(GTK_DIALOG(msgbox));
gtk_widget_destroy(msgbox);
msgbox = NULL;
return retval;
} // do_msgbox
static void MojoGui_gtkplus2_msgbox(const char *title, const char *text)
{
do_msgbox(title, text, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, 0, NULL);
} // MojoGui_gtkplus2_msgbox
static boolean MojoGui_gtkplus2_promptyn(const char *title, const char *text,
boolean defval)
{
gint rc = do_msgbox(title, text, GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO,
defval ? GTK_RESPONSE_YES : GTK_RESPONSE_NO,
NULL);
return (rc == GTK_RESPONSE_YES);
} // MojoGui_gtkplus2_promptyn
static void promptynanButtonCallback(GtkWidget *_msgbox)
{
char *always = xstrdup(_("_Always"));
char *never = xstrdup(_("N_ever"));
gtk_dialog_add_buttons(GTK_DIALOG(_msgbox),
GTK_STOCK_YES, GTK_RESPONSE_YES,
GTK_STOCK_NO, GTK_RESPONSE_NO,
always, 1,
never, 0,
NULL);
free(always);
free(never);
} // promptynanButtonCallback
static MojoGuiYNAN MojoGui_gtkplus2_promptynan(const char *title,
const char *text,
boolean defval)
{
const gint rc = do_msgbox(title, text, GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
defval ? GTK_RESPONSE_YES : GTK_RESPONSE_NO,
promptynanButtonCallback);
switch (rc)
{
case GTK_RESPONSE_YES: return MOJOGUI_YES;
case GTK_RESPONSE_NO: return MOJOGUI_NO;
case 1: return MOJOGUI_ALWAYS;
case 0: return MOJOGUI_NEVER;
} // switch
assert(false && "BUG: unhandled case in switch statement");
return MOJOGUI_NO; // just in case.
} // MojoGui_gtkplus2_promptynan
static GtkWidget *create_button(GtkWidget *box, const char *iconname,
const char *text,
void (*signal_callback)
(GtkButton *button, gpointer data))
{
GtkWidget *button = gtk_button_new_with_mnemonic(text);
GtkWidget *image = gtk_image_new_from_stock(iconname, GTK_ICON_SIZE_BUTTON);
gtk_button_set_image (GTK_BUTTON(button), image);
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 6);
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(signal_callback), NULL);
return button;
} // create_button
static void free_splash(guchar *pixels, gpointer data)
{
free(pixels);
} // free_splash
static GtkWidget *build_splash(const MojoGuiSplash *splash)
{
GtkWidget *retval = NULL;
GdkPixbuf *pixbuf = NULL;
guchar *rgba = NULL;
const uint32 splashlen = splash->w * splash->h * 4;
if (splash->position == MOJOGUI_SPLASH_NONE)
return NULL;
if ((splash->rgba == NULL) || (splashlen == 0))
return NULL;
rgba = (guchar *) xmalloc(splashlen);
memcpy(rgba, splash->rgba, splashlen);
pixbuf = gdk_pixbuf_new_from_data(rgba, GDK_COLORSPACE_RGB, TRUE, 8,
splash->w, splash->h, splash->w * 4,
free_splash, NULL);
if (pixbuf == NULL)
free(rgba);
else
{
retval = gtk_image_new_from_pixbuf(pixbuf);
g_object_unref(pixbuf); // retval adds a ref to pixbuf, so lose our's.
if (retval != NULL)
gtk_widget_show(retval);
} // else
return retval;
} // build_splash
static GtkWidget *create_gtkwindow(const char *title,
const MojoGuiSplash *_splash)
{
GtkWidget *splashbox = NULL;
GtkWidget *window;
GtkWidget *widget;
GtkWidget *box;
GtkWidget *alignment;
GtkWidget *hbox;
currentpage = PAGE_INTRO;
canfwd = TRUE;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
gtk_window_set_title(GTK_WINDOW(window), title);
gtk_container_set_border_width(GTK_CONTAINER(window), 8);
GdkPixbuf *icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
"system-software-installer",
48, 0, NULL);
if (icon)
gtk_window_set_icon(GTK_WINDOW(window), icon);
assert(splash == NULL);
splash = build_splash(_splash);
if (splash != NULL)
{
// !!! FIXME: MOJOGUI_SPLASH_BACKGROUND?
const MojoGuiSplashPos pos = _splash->position;
if ((pos == MOJOGUI_SPLASH_LEFT) || (pos == MOJOGUI_SPLASH_RIGHT))
{
splashbox = gtk_hbox_new(FALSE, 6);
gtk_widget_show(splashbox);
gtk_container_add(GTK_CONTAINER(window), splashbox);
if (pos == MOJOGUI_SPLASH_LEFT)
gtk_box_pack_start(GTK_BOX(splashbox), splash, FALSE, FALSE, 6);
else
gtk_box_pack_end(GTK_BOX(splashbox), splash, FALSE, FALSE, 6);
} // if
else if ((pos == MOJOGUI_SPLASH_TOP) || (pos == MOJOGUI_SPLASH_BOTTOM))
{
splashbox = gtk_vbox_new(FALSE, 6);
gtk_widget_show(splashbox);
gtk_container_add(GTK_CONTAINER(window), splashbox);
if (pos == MOJOGUI_SPLASH_TOP)
gtk_box_pack_start(GTK_BOX(splashbox), splash, FALSE, FALSE, 6);
else
gtk_box_pack_end(GTK_BOX(splashbox), splash, FALSE, FALSE, 6);
} // else if
} // if
if (splashbox == NULL) // no splash, use the window for the top container.
splashbox = window;
box = gtk_vbox_new(FALSE, 6);
gtk_widget_show(box);
gtk_container_add(GTK_CONTAINER(splashbox), box);
pagetitle = gtk_label_new("");
gtk_widget_show(pagetitle);
gtk_box_pack_start(GTK_BOX(box), pagetitle, FALSE, TRUE, 16);
notebook = gtk_notebook_new();
gtk_widget_show(notebook);
gtk_container_set_border_width(GTK_CONTAINER(notebook), 0);
gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), FALSE);
gtk_widget_set_size_request(notebook,
(gint) (((float) gdk_screen_width()) * 0.4),
(gint) (((float) gdk_screen_height()) * 0.4));
widget = gtk_hbutton_box_new();
gtk_widget_show(widget);
gtk_box_pack_start(GTK_BOX(box), widget, FALSE, FALSE, 0);
gtk_button_box_set_layout(GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_END);
gtk_button_box_set_child_ipadding(GTK_BUTTON_BOX (widget), 6, 0);
gtk_button_box_set_spacing(GTK_BUTTON_BOX (widget), 6);
box = widget;
cancel = create_button(box, "gtk-cancel", _("Cancel"), signal_clicked);
back = create_button(box, "gtk-go-back", _("Back"), signal_clicked);
next = create_button(box, "gtk-go-forward", _("Next"), signal_clicked);
finish = create_button(box, "gtk-goto-last", _("Finish"), signal_clicked);
gtk_widget_hide(finish);
// !!! FIXME: intro page.
widget = gtk_vbox_new(FALSE, 0);
gtk_widget_show(widget);
gtk_container_add(GTK_CONTAINER(notebook), widget);
// README/EULA page.
widget = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(
GTK_SCROLLED_WINDOW(widget),
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
gtk_scrolled_window_set_shadow_type(
GTK_SCROLLED_WINDOW(widget),
GTK_SHADOW_IN);
gtk_widget_show(widget);
gtk_container_add(GTK_CONTAINER(notebook), widget);
readme = gtk_text_view_new();
gtk_widget_show(readme);
gtk_container_add(GTK_CONTAINER(widget), readme);
gtk_text_view_set_editable(GTK_TEXT_VIEW(readme), FALSE);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(readme), GTK_WRAP_NONE);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(readme), FALSE);
gtk_text_view_set_left_margin(GTK_TEXT_VIEW(readme), 4);
gtk_text_view_set_right_margin(GTK_TEXT_VIEW(readme), 4);
// !!! FIXME: options page.
box = gtk_vbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_container_add(GTK_CONTAINER(notebook), box);
// Destination page
box = gtk_vbox_new(FALSE, 0);
gtk_widget_show(box);
hbox = gtk_hbox_new (FALSE, 6);
widget = gtk_label_new(_("Folder:"));
gtk_widget_show(widget);
gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
gtk_label_set_justify(GTK_LABEL(widget), GTK_JUSTIFY_CENTER);
gtk_label_set_line_wrap(GTK_LABEL(widget), FALSE);
alignment = gtk_alignment_new(0.5, 0.5, 1, 0);
destination = gtk_combo_box_entry_new_text();
gtk_signal_connect(GTK_OBJECT(destination), "changed",
GTK_SIGNAL_FUNC(signal_dest_changed), NULL);
gtk_container_add(GTK_CONTAINER(alignment), destination);
gtk_box_pack_start(GTK_BOX(hbox), alignment, TRUE, TRUE, 0);
browse = create_button(hbox, "gtk-open",
_("B_rowse..."), signal_browse_clicked);
gtk_widget_show_all (hbox);
gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(notebook), box);
// Product key page
box = gtk_vbox_new(FALSE, 0);
gtk_widget_show(box);
widget = gtk_label_new(_("Please enter your product key"));
gtk_label_set_justify(GTK_LABEL(widget), GTK_JUSTIFY_CENTER);
gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE);
gtk_widget_show(widget);
gtk_box_pack_start(GTK_BOX(box), widget, FALSE, TRUE, 0);
hbox = gtk_hbox_new(FALSE, 0);
gtk_widget_show(hbox);
productkey = gtk_entry_new();
gtk_entry_set_editable(GTK_ENTRY(productkey), TRUE);
gtk_entry_set_visibility(GTK_ENTRY(productkey), TRUE);
gtk_widget_show(productkey);
gtk_box_pack_start(GTK_BOX(hbox), productkey, TRUE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(notebook), box);
// Progress page
box = gtk_vbox_new(FALSE, 6);
gtk_widget_show(box);
alignment = gtk_alignment_new(0.5, 0.5, 1, 0);
gtk_widget_show(alignment);
progressbar = gtk_progress_bar_new();
gtk_widget_show(progressbar);
gtk_container_add(GTK_CONTAINER(alignment), progressbar);
gtk_box_pack_start(GTK_BOX(box), alignment, FALSE, TRUE, 0);
progresslabel = gtk_label_new("");
gtk_widget_show(progresslabel);
gtk_box_pack_start(GTK_BOX(box), progresslabel, FALSE, TRUE, 0);
gtk_label_set_justify(GTK_LABEL(progresslabel), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap(GTK_LABEL(progresslabel), FALSE);
gtk_container_add(GTK_CONTAINER(notebook), box);
// !!! FIXME: final page.
widget = gtk_vbox_new(FALSE, 0);
gtk_widget_show(widget);
gtk_container_add(GTK_CONTAINER(notebook), widget);
finallabel = gtk_label_new("");
gtk_widget_show(finallabel);
gtk_box_pack_start(GTK_BOX(widget), finallabel, FALSE, TRUE, 0);
gtk_label_set_justify(GTK_LABEL(finallabel), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap(GTK_LABEL(finallabel), TRUE);
gtk_signal_connect(GTK_OBJECT(window), "delete-event",
GTK_SIGNAL_FUNC(signal_delete), NULL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_show(window);
gtk_widget_grab_focus(next);
return window;
} // create_gtkwindow
static boolean MojoGui_gtkplus2_start(const char *title,
const MojoGuiSplash *splash)
{
gtkwindow = create_gtkwindow(title, splash);
return (gtkwindow != NULL);
} // MojoGui_gtkplus2_start
static void MojoGui_gtkplus2_stop(void)
{
assert(msgbox == NULL);
if (gtkwindow != NULL)
gtk_widget_destroy(gtkwindow);
gtkwindow = NULL;
pagetitle = NULL;
finallabel = NULL;
progresslabel = NULL;
progressbar = NULL;
destination = NULL;
productkey = NULL;
notebook = NULL;
readme = NULL;
cancel = NULL;
back = NULL;
next = NULL;
finish = NULL;
splash = NULL;
} // MojoGui_gtkplus2_stop
static int MojoGui_gtkplus2_readme(const char *name, const uint8 *data,
size_t datalen, boolean can_back,
boolean can_fwd)
{
GtkTextBuffer *textbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(readme));
gtk_text_buffer_set_text(textbuf, (const gchar *) data, datalen);
return run_wizard(name, PAGE_README, can_back, can_fwd, true, can_fwd);
} // MojoGui_gtkplus2_readme
static void set_option_tree_sensitivity(MojoGuiSetupOptions *opts, boolean val)
{
if (opts != NULL)
{
gtk_widget_set_sensitive((GtkWidget *) opts->guiopaque, val);
set_option_tree_sensitivity(opts->next_sibling, val);
set_option_tree_sensitivity(opts->child, val && opts->value);
} // if
} // set_option_tree_sensitivity
static void signal_option_toggled(GtkToggleButton *toggle, gpointer data)
{
MojoGuiSetupOptions *opts = (MojoGuiSetupOptions *) data;
const boolean enabled = gtk_toggle_button_get_active(toggle);
opts->value = enabled;
set_option_tree_sensitivity(opts->child, enabled);
} // signal_option_toggled
static GtkWidget *new_option_level(GtkWidget *box)
{
GtkWidget *alignment = gtk_alignment_new(0.0, 0.5, 0, 0);
GtkWidget *retval = gtk_vbox_new(FALSE, 0);
gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 15, 0);
gtk_widget_show(alignment);
gtk_widget_show(retval);
gtk_container_add(GTK_CONTAINER(alignment), retval);
gtk_box_pack_start(GTK_BOX(box), alignment, TRUE, TRUE, 0);
return retval;
} // new_option_level
// use this to generate a tooltip only as needed.
static GtkTooltips *get_tip(GtkTooltips **_tip)
{
if (*_tip == NULL)
{
GtkTooltips *tip = gtk_tooltips_new();
gtk_tooltips_enable(tip);
*_tip = tip;
} // if
return *_tip;
} // get_tip
static void build_options(MojoGuiSetupOptions *opts, GtkWidget *box,
gboolean sensitive)
{
if (opts != NULL)
{
GtkTooltips *tip = NULL;
GtkWidget *widget = NULL;
if (opts->is_group_parent)
{
MojoGuiSetupOptions *kids = opts->child;
GtkWidget *childbox = NULL;
GtkWidget *alignment = gtk_alignment_new(0.0, 0.5, 0, 0);
gtk_widget_show(alignment);
widget = gtk_label_new(opts->description);
opts->guiopaque = widget;
gtk_widget_set_sensitive(widget, sensitive);
gtk_widget_show(widget);
gtk_label_set_justify(GTK_LABEL(widget), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap(GTK_LABEL(widget), FALSE);
gtk_container_add(GTK_CONTAINER(alignment), widget);
gtk_box_pack_start(GTK_BOX(box), alignment, FALSE, TRUE, 0);
if (opts->tooltip != NULL)
gtk_tooltips_set_tip(get_tip(&tip), widget, opts->tooltip, 0);
widget = NULL;
childbox = new_option_level(box);
while (kids)
{
widget = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(widget),
kids->description);
kids->guiopaque = widget;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
kids->value);
gtk_widget_set_sensitive(widget, sensitive);
gtk_widget_show(widget);
gtk_box_pack_start(GTK_BOX(childbox), widget, FALSE, TRUE, 0);
gtk_signal_connect(GTK_OBJECT(widget), "toggled",
GTK_SIGNAL_FUNC(signal_option_toggled), kids);
if (kids->tooltip != NULL)
gtk_tooltips_set_tip(get_tip(&tip),widget,kids->tooltip,0);
if (kids->child != NULL)
{
build_options(kids->child, new_option_level(childbox),
sensitive);
} // if
kids = kids->next_sibling;
} // while
} // if
else
{
widget = gtk_check_button_new_with_label(opts->description);
opts->guiopaque = widget;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
opts->value);
gtk_widget_set_sensitive(widget, sensitive);
gtk_widget_show(widget);
gtk_box_pack_start(GTK_BOX(box), widget, FALSE, TRUE, 0);
gtk_signal_connect(GTK_OBJECT(widget), "toggled",
GTK_SIGNAL_FUNC(signal_option_toggled), opts);
if (opts->tooltip != NULL)
gtk_tooltips_set_tip(get_tip(&tip), widget, opts->tooltip, 0);
if (opts->child != NULL)
{
build_options(opts->child, new_option_level(box),
((sensitive) && (opts->value)) );
} // if
} // else
build_options(opts->next_sibling, box, sensitive);
} // if
} // build_options
static int MojoGui_gtkplus2_options(MojoGuiSetupOptions *opts,
boolean can_back, boolean can_fwd)
{
int retval;
GtkWidget *box;
GtkWidget *page; // this is a vbox.
page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), PAGE_OPTIONS);
box = gtk_vbox_new(FALSE, 0);
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(page), box, FALSE, FALSE, 0);
build_options(opts, box, TRUE);
retval = run_wizard(_("Options"), PAGE_OPTIONS,
can_back, can_fwd, true, can_fwd);
gtk_widget_destroy(box);
return retval;
} // MojoGui_gtkplus2_options
static char *MojoGui_gtkplus2_destination(const char **recommends, int recnum,
int *command, boolean can_back,
boolean can_fwd)
{
GtkComboBox *combo = GTK_COMBO_BOX(destination);
const boolean fwd_at_start = ( (recnum > 0) && (*(recommends[0])) );
gchar *str = NULL;
char *retval = NULL;
int i;
for (i = 0; i < recnum; i++)
gtk_combo_box_append_text(combo, recommends[i]);
gtk_combo_box_set_active (combo, 0);
*command = run_wizard(_("Destination"), PAGE_DEST,
can_back, can_fwd, true, fwd_at_start);
str = gtk_combo_box_get_active_text(combo);
// shouldn't ever be empty ("next" should be disabled in that case).
assert( (*command <= 0) || ((str != NULL) && (*str != '\0')) );
retval = xstrdup(str);
g_free(str);
for (i = recnum-1; i >= 0; i--)
gtk_combo_box_remove_text(combo, i);
return retval;
} // MojoGui_gtkplus2_destination
static int MojoGui_gtkplus2_productkey(const char *desc, const char *fmt,
char *buf, const int buflen,
boolean can_back, boolean can_fwd)
{
gchar *str = NULL;
int retval = 0;
const boolean fwd_at_start = isValidProductKey(fmt, buf);
gtk_entry_set_max_length(GTK_ENTRY(productkey), buflen - 1);
gtk_entry_set_width_chars(GTK_ENTRY(productkey), buflen - 1);
gtk_entry_set_text(GTK_ENTRY(productkey), (gchar *) buf);
const guint connid = gtk_signal_connect(GTK_OBJECT(productkey), "changed",
GTK_SIGNAL_FUNC(signal_productkey_changed),
(void *) fmt);
retval = run_wizard(desc, PAGE_PRODUCTKEY,
can_back, can_fwd, true, fwd_at_start);
gtk_signal_disconnect(GTK_OBJECT(productkey), connid);
str = gtk_editable_get_chars(GTK_EDITABLE(productkey), 0, -1);
// should never be invalid ("next" should be disabled in that case).
assert( (retval <= 0) || ((str) && (isValidProductKey(fmt, str))) );
assert(strlen(str) < buflen);
strcpy(buf, (char *) str);
g_free(str);
gtk_entry_set_text(GTK_ENTRY(productkey), "");
return retval;
} // MojoGui_gtkplus2_productkey
static boolean MojoGui_gtkplus2_insertmedia(const char *medianame)
{
gint rc = 0;
// !!! FIXME: Use stock GTK icon for "media"?
// !!! FIXME: better text.
const char *title = xstrdup(_("Media change"));
// !!! FIXME: better text.
const char *fmt = xstrdup(_("Please insert '%0'"));
const char *text = format(fmt, medianame);
rc = do_msgbox(title, text, GTK_MESSAGE_WARNING,
GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, NULL);
free((void *) text);
free((void *) fmt);
free((void *) title);
return (rc == GTK_RESPONSE_OK);
} // MojoGui_gtkplus2_insertmedia
static void MojoGui_gtkplus2_progressitem(void)
{
// no-op in this UI target.
} // MojoGui_gtkplus2_progressitem
static boolean MojoGui_gtkplus2_progress(const char *type, const char *component,
int percent, const char *item,
boolean can_cancel)
{
static uint32 lastTicks = 0;
const uint32 ticks = ticks();
int rc;
if ((ticks - lastTicks) > 200) // just not to spam this...
{
GtkProgressBar *progress = GTK_PROGRESS_BAR(progressbar);
if (percent < 0)
gtk_progress_bar_pulse(progress);
else
gtk_progress_bar_set_fraction(progress, ((gdouble) percent) / 100.0);
gtk_progress_bar_set_text(progress, component);
gtk_label_set_text(GTK_LABEL(progresslabel), item);
lastTicks = ticks;
} // if
prepare_wizard(type, PAGE_PROGRESS, false, false, can_cancel, false);
rc = pump_events();
assert( (rc == ((int) CLICK_CANCEL)) || (rc == ((int) CLICK_NONE)) );
return (rc != CLICK_CANCEL);
} // MojoGui_gtkplus2_progress
static void MojoGui_gtkplus2_final(const char *msg)
{
gtk_widget_hide(next);
gtk_widget_show(finish);
gtk_label_set_text(GTK_LABEL(finallabel), msg);
run_wizard(_("Finish"), PAGE_FINAL, false, true, false, true);
} // MojoGui_gtkplus2_final
// end of gui_gtkplus2.c ...

File diff suppressed because it is too large Load Diff

View File

@@ -1,655 +0,0 @@
/**
* MojoSetup; a portable, flexible installation application.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*
Copyright (c) 2006-2010 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>
*/
#if !SUPPORT_GUI_STDIO
#error Something is wrong in the build system.
#endif
#define BUILDING_EXTERNAL_PLUGIN 1
#include "gui.h"
MOJOGUI_PLUGIN(stdio)
#if !GUI_STATIC_LINK_STDIO
CREATE_MOJOGUI_ENTRY_POINT(stdio)
#endif
#include <ctype.h>
static char *lastProgressType = NULL;
static char *lastComponent = NULL;
static uint32 percentTicks = 0;
static int read_stdin(char *buf, int len)
{
if (fgets(buf, len, stdin) == NULL)
return -1;
len = strlen(buf) - 1;
while ( (len >= 0) && ((buf[len] == '\n') || (buf[len] == '\r')) )
buf[len--] = '\0';
return len+1;
} // read_stdin
static int readstr(const char *prompt, char *buf, int len,
boolean back, boolean fwd)
{
// !!! FIXME: if read_stdin() returns -1, we return 0, which makes it
// !!! FIXME: indistinguishable from "user hit enter" ... maybe we should
// !!! FIXME: abort in read_stdin() if i/o fails?
int retval = 0;
char *backstr = (back) ? xstrdup(_("back")) : NULL;
if (prompt != NULL)
printf("%s\n", prompt);
if (back)
{
char *fmt = xstrdup(_("Type '%0' to go back."));
char *msg = format(fmt, backstr);
printf("%s\n", msg);
free(msg);
free(fmt);
} // if
if (fwd)
{
printf("%s", _("Press enter to continue."));
printf("\n");
} // if
printf("%s",_("> "));
fflush(stdout);
if ((retval = read_stdin(buf, len)) >= 0)
{
if ((back) && (strcmp(buf, backstr) == 0)) // !!! FIXME: utf8casecmp?
retval = -1;
} // if
free(backstr);
return retval;
} // readstr
static uint8 MojoGui_stdio_priority(boolean istty)
{
// if not a tty and no other GUI plugins worked out, let the base
// application try to spawn a terminal and try again. If it can't do so,
// it will panic() and thus end the process, so we don't end up blocking
// on some prompt the user can't see.
if (!istty)
return MOJOGUI_PRIORITY_NEVER_TRY;
return MOJOGUI_PRIORITY_TRY_ABSOLUTELY_LAST; // always a last resort.
} // MojoGui_stdio_priority
static boolean MojoGui_stdio_init(void)
{
percentTicks = 0;
return true; // always succeeds.
} // MojoGui_stdio_init
static void MojoGui_stdio_deinit(void)
{
free(lastProgressType);
free(lastComponent);
lastProgressType = NULL;
lastComponent = NULL;
} // MojoGui_stdio_deinit
static void MojoGui_stdio_msgbox(const char *title, const char *text)
{
char buf[128];
char *fmt = xstrdup(_("NOTICE: %0\n[hit enter]"));
char *msg = format(fmt, text);
printf("%s\n", msg);
free(msg);
free(fmt);
fflush(stdout);
read_stdin(buf, sizeof (buf));
} // MojoGui_stdio_msgbox
static boolean MojoGui_stdio_promptyn(const char *title, const char *text,
boolean defval)
{
boolean retval = false;
if (!feof(stdin))
{
const char *_fmt = ((defval) ? _("%0 [Y/n]: ") : _("%0 [y/N]: "));
char *fmt = xstrdup(_fmt);
char *msg = format(fmt, text);
char *localized_no = xstrdup(_("N"));
char *localized_yes = xstrdup(_("Y"));
boolean getout = false;
char buf[128];
while (!getout)
{
int rc = 0;
getout = true; // we may reset this later.
printf("%s", msg);
fflush(stdout);
rc = read_stdin(buf, sizeof (buf));
if (rc < 0)
retval = false;
else if (rc == 0)
retval = defval;
else if (strcasecmp(buf, localized_no) == 0)
retval = false;
else if (strcasecmp(buf, localized_yes) == 0)
retval = true;
else
getout = false; // try again.
} // while
free(localized_yes);
free(localized_no);
free(msg);
free(fmt);
} // if
return retval;
} // MojoGui_stdio_promptyn
static MojoGuiYNAN MojoGui_stdio_promptynan(const char *title, const char *txt,
boolean defval)
{
MojoGuiYNAN retval = MOJOGUI_NO;
if (!feof(stdin))
{
char *fmt = xstrdup(_("%0\n[y/n/Always/Never]: "));
char *msg = format(fmt, txt);
char *localized_no = xstrdup(_("N"));
char *localized_yes = xstrdup(_("Y"));
char *localized_always = xstrdup(_("Always"));
char *localized_never = xstrdup(_("Never"));
boolean getout = false;
char buf[128];
while (!getout)
{
int rc = 0;
getout = true; // we may reset this later.
printf("%s\n", msg);
fflush(stdout);
rc = read_stdin(buf, sizeof (buf));
if (rc < 0)
retval = MOJOGUI_NO;
else if (rc == 0)
retval = (defval) ? MOJOGUI_YES : MOJOGUI_NO;
else if (strcasecmp(buf, localized_no) == 0)
retval = MOJOGUI_NO;
else if (strcasecmp(buf, localized_yes) == 0)
retval = MOJOGUI_YES;
else if (strcasecmp(buf, localized_always) == 0)
retval = MOJOGUI_ALWAYS;
else if (strcasecmp(buf, localized_never) == 0)
retval = MOJOGUI_NEVER;
else
getout = false; // try again.
} // while
free(localized_never);
free(localized_always);
free(localized_yes);
free(localized_no);
free(msg);
free(fmt);
} // if
return retval;
} // MojoGui_stdio_promptynan
static boolean MojoGui_stdio_start(const char *title,
const MojoGuiSplash *splash)
{
printf("%s\n", title);
return true;
} // MojoGui_stdio_start
static void MojoGui_stdio_stop(void)
{
// no-op.
} // MojoGui_stdio_stop
static void dumb_pager(const char *name, const char *data, size_t datalen)
{
const int MAX_PAGE_LINES = 21;
char *fmt = xstrdup(_("(%0-%1 of %2 lines, see more?)"));
int i = 0;
int w = 0;
int linecount = 0;
boolean getout = false;
char **lines = splitText(data, 80, &linecount, &w);
assert(linecount >= 0);
printf("%s\n", name);
if (lines == NULL) // failed to parse?!
printf("%s\n", data); // just dump it all. Oh well.
else
{
int printed = 0;
do
{
for (i = 0; (i < MAX_PAGE_LINES) && (printed < linecount); i++)
printf("%s", lines[printed++]);
if (printed >= linecount)
getout = true;
else
{
char *msg = NULL;
printf("\n");
msg = format(fmt, numstr((printed-i)+1),
numstr(printed), numstr(linecount));
getout = !MojoGui_stdio_promptyn("", msg, true);
free(msg);
printf("\n");
} // else
} while (!getout);
for (i = 0; i < linecount; i++)
free(lines[i]);
free(lines);
} // while
free(fmt);
} // dumb_pager
static int MojoGui_stdio_readme(const char *name, const uint8 *_data,
size_t datalen, boolean can_back,
boolean can_fwd)
{
const char *data = (const char *) _data;
char buf[256];
int retval = -1;
boolean failed = true;
// !!! FIXME: popen() isn't reliable.
#if 0 //PLATFORM_UNIX
const size_t namelen = strlen(name);
const char *programs[] = { getenv("PAGER"), "more", "less -M", "less" };
int i = 0;
// flush streams, so output doesn't mingle with the popen()'d process.
fflush(stdout);
fflush(stderr);
for (i = 0; i < STATICARRAYLEN(programs); i++)
{
const char *cmd = programs[i];
if (cmd != NULL)
{
FILE *io = popen(cmd, "w");
if (io != NULL)
{
failed = false;
if (!failed) failed = (fwrite("\n", 1, 1, io) != 1);
if (!failed) failed = (fwrite(name, namelen, 1, io) != 1);
if (!failed) failed = (fwrite("\n", 1, 1, io) != 1);
if (!failed) failed = (fwrite(data, datalen, 1, io) != 1);
if (!failed) failed = (fwrite("\n", 1, 1, io) != 1);
failed |= (pclose(io) != 0); // call whether we failed or not.
if (!failed)
break; // it worked, we're done!
} // if
} // if
} // for
#endif // PLATFORM_UNIX
if (failed) // We're not Unix, or none of the pagers worked?
dumb_pager(name, data, datalen);
// Put up the "hit enter to continue (or 'back' to go back)" prompt,
// but only if there's an choice to be made here.
if ((!can_back) || (readstr(NULL, buf, sizeof (buf), can_back, true) >= 0))
retval = 1;
return retval;
} // MojoGui_stdio_readme
static void toggle_option(MojoGuiSetupOptions *parent,
MojoGuiSetupOptions *opts, int *line, int target)
{
if ((opts != NULL) && (target > *line))
{
if (!opts->is_group_parent)
{
if (++(*line) == target)
{
const boolean toggled = ((opts->value) ? false : true);
// "radio buttons" in a group?
if ((parent) && (parent->is_group_parent))
{
if (toggled) // drop unless we weren't the current toggle.
{
// set all siblings to false...
MojoGuiSetupOptions *i = parent->child;
while (i != NULL)
{
i->value = false;
i = i->next_sibling;
} // while
opts->value = true; // reset us to be true.
} // if
} // if
else // individual "check box" was chosen.
{
opts->value = toggled;
} // else
return; // we found it, bail.
} // if
} // if
if (opts->value) // if option is toggled on, descend to children.
toggle_option(opts, opts->child, line, target);
toggle_option(parent, opts->next_sibling, line, target);
} // if
} // toggle_option
static void print_options(MojoGuiSetupOptions *opts, int *line, int level)
{
if (opts != NULL)
{
int i;
int spacing = 1;
if (opts->is_group_parent)
spacing += 6;
else
{
(*line)++;
printf("%2d [%c]", *line, opts->value ? 'X' : ' ');
} // else
for (i = 0; i < (level + spacing); i++)
putchar(' ');
printf("%s%s\n", opts->description, opts->is_group_parent ? ":" : "");
if ((opts->value) || (opts->is_group_parent))
print_options(opts->child, line, level+1);
print_options(opts->next_sibling, line, level);
} // if
} // print_options
static int MojoGui_stdio_options(MojoGuiSetupOptions *opts,
boolean can_back, boolean can_fwd)
{
const char *inst_opts_str = xstrdup(_("Options"));
const char *prompt = xstrdup(_("Choose number to change."));
int retval = -1;
boolean getout = false;
char buf[128];
int len = 0;
while (!getout)
{
int line = 0;
printf("\n\n");
printf("%s", inst_opts_str);
printf("\n");
print_options(opts, &line, 1);
printf("\n");
if ((len = readstr(prompt, buf, sizeof (buf), can_back, true)) < 0)
getout = true;
else if (len == 0)
{
getout = true;
retval = 1;
} // else if
else
{
char *endptr = NULL;
int target = (int) strtol(buf, &endptr, 10);
if (*endptr == '\0') // complete string was a valid number?
{
line = 0;
toggle_option(NULL, opts, &line, target);
} // if
} // else
} // while
free((void *) inst_opts_str);
free((void *) prompt);
return retval;
} // MojoGui_stdio_options
static char *MojoGui_stdio_destination(const char **recommends, int recnum,
int *command, boolean can_back,
boolean can_fwd)
{
const char *instdeststr = xstrdup(_("Destination"));
const char *prompt = NULL;
char *retval = NULL;
boolean getout = false;
char buf[128];
int len = 0;
int i = 0;
*command = -1;
if (recnum > 0)
prompt = xstrdup(_("Choose install destination by number (hit enter for #1), or enter your own."));
else
prompt = xstrdup(_("Enter path where files will be installed."));
while (!getout)
{
printf("\n\n%s\n", instdeststr);
for (i = 0; i < recnum; i++)
printf(" %2d %s\n", i+1, recommends[i]);
printf("\n");
if ((len = readstr(prompt, buf, sizeof (buf), can_back, false)) < 0)
getout = true;
else if ((len == 0) && (recnum > 0)) // default to first in list.
{
retval = xstrdup(recommends[0]);
*command = 1;
getout = true;
} // else if
else if (len > 0)
{
char *endptr = NULL;
int target = (int) strtol(buf, &endptr, 10);
// complete string was a valid number?
if ((*endptr == '\0') && (target > 0) && (target <= recnum))
retval = xstrdup(recommends[target-1]);
else
retval = xstrdup(buf);
*command = 1;
getout = true;
} // else
} // while
free((void *) prompt);
free((void *) instdeststr);
return retval;
} // MojoGui_stdio_destination
static int MojoGui_stdio_productkey(const char *desc, const char *fmt,
char *buf, const int buflen,
boolean can_back, boolean can_fwd)
{
const char *prompt = xstrdup(_("Please enter your product key"));
char *defval = ((*buf) ? xstrdup(buf) : NULL);
boolean getout = false;
int retval = -1;
char *msg = NULL;
if (defval != NULL)
{
char *locfmt = xstrdup(_("(just press enter to use '%0')"));
msg = format(locfmt, defval);
free(locfmt);
} // if
while (!getout)
{
int len;
printf("\n\n%s\n", desc);
if (msg != NULL)
printf("%s\n", msg);
if ((len = readstr(prompt, buf, buflen, can_back, false)) < 0)
getout = true;
else
{
if ((len == 0) && (defval != NULL))
strcpy(buf, defval);
if (isValidProductKey(fmt, buf))
{
retval = 1;
getout = true;
} // else if
else
{
// We can't check the input character-by-character, so reuse
// the failed-verification localized string.
printf("\n%s\n\n",
_("That key appears to be invalid. Please try again."));
} // else
} // else
} // while
free(msg);
free(defval);
free((void *) prompt);
return retval;
} // MojoGui_stdio_productkey
static boolean MojoGui_stdio_insertmedia(const char *medianame)
{
char buf[32];
char *fmt = xstrdup(_("Please insert '%0'"));
char *msg = format(fmt, medianame);
printf("%s\n", _("Media change"));
printf("%s\n", msg);
free(msg);
free(fmt);
return (readstr(NULL, buf, sizeof (buf), false, true) >= 0);
} // MojoGui_stdio_insertmedia
static void MojoGui_stdio_progressitem(void)
{
// force new line of output on next call to MojoGui_stdio_progress()
percentTicks = 0;
} // MojoGui_stdio_progressitem
static boolean MojoGui_stdio_progress(const char *type, const char *component,
int percent, const char *item,
boolean can_cancel)
{
const uint32 now = ticks();
if ( (lastComponent == NULL) ||
(strcmp(lastComponent, component) != 0) ||
(lastProgressType == NULL) ||
(strcmp(lastProgressType, type) != 0) )
{
free(lastProgressType);
free(lastComponent);
lastProgressType = xstrdup(type);
lastComponent = xstrdup(component);
printf("%s\n%s\n", type, component);
} // if
// limit update spam... will only write every one second, tops,
// on any given filename, but it writes each filename at least once
// so it doesn't look like we only installed a few things.
if (percentTicks <= now)
{
char *fmt = NULL;
char *msg = NULL;
percentTicks = now + 1000;
if (percent < 0)
printf("%s\n", item);
else
{
fmt = xstrdup(_("%0 (total progress: %1%%)"));
msg = format(fmt, item, numstr(percent));
printf("%s\n", msg);
free(msg);
free(fmt);
} // else
} // if
return true;
} // MojoGui_stdio_progress
static void MojoGui_stdio_final(const char *msg)
{
printf("%s\n\n", msg);
fflush(stdout);
} // MojoGui_stdio_final
// end of gui_stdio.c ...

File diff suppressed because it is too large Load Diff

View File

@@ -1,48 +0,0 @@
This is libfetch, from FreeBSD.
I grabbed it from CVS, like this:
cvs -z9 -dfreebsdanoncvs@anoncvs.FreeBSD.org:/home/ncvs co src/lib/libfetch
Checkout was from May 5th, 2007, 1pm EST.
This just has minor modifications to make it play nicely with our build system,
and code, and stuff we don't need was trimmed out.
Changes made for MojoSetup that aren't part of a virgin copy of libfetch are
noted with "#if __MOJOSETUP__" sections.
Here is the libfetch copyright from common.c ...
/*-
* Copyright (c) 1998-2004 Dag-Erling Co<43>dan Sm<53>rgrav
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
--ryan.

File diff suppressed because it is too large Load Diff

View File

@@ -1,135 +0,0 @@
/*-
* Copyright (c) 1998-2004 Dag-Erling Co<43>dan Sm<53>rgrav
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/lib/libfetch/common.h,v 1.28 2004/09/21 18:35:20 des Exp $
*/
#ifndef _COMMON_H_INCLUDED
#define _COMMON_H_INCLUDED
#define FTP_DEFAULT_PORT 21
#define HTTP_DEFAULT_PORT 80
#define FTP_DEFAULT_PROXY_PORT 21
#define HTTP_DEFAULT_PROXY_PORT 3128
#ifdef WITH_SSL
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif
/* Connection */
typedef struct fetchconn conn_t;
struct fetchconn {
int sd; /* socket descriptor */
char *buf; /* buffer */
size_t bufsize; /* buffer size */
size_t buflen; /* length of buffer contents */
int err; /* last protocol reply code */
#ifdef WITH_SSL
SSL *ssl; /* SSL handle */
SSL_CTX *ssl_ctx; /* SSL context */
X509 *ssl_cert; /* server certificate */
SSL_METHOD *ssl_meth; /* SSL method */
#endif
int ref; /* reference count */
};
/* Structure used for error message lists */
struct fetcherr {
const int num;
const int cat;
const char *string;
};
/* for _fetch_writev */
struct iovec;
void _fetch_seterr(struct fetcherr *, int);
void _fetch_syserr(void);
#if __MOJOSETUP__
void _fetch_info(const char *fmt, ...) ISPRINTF(1,2);
#else
void _fetch_info(const char *, ...);
#endif
int _fetch_default_port(const char *);
int _fetch_default_proxy_port(const char *);
int _fetch_bind(int, int, const char *);
conn_t *_fetch_connect(const char *, int, int, int);
conn_t *_fetch_reopen(int);
conn_t *_fetch_ref(conn_t *);
int _fetch_ssl(conn_t *, int);
ssize_t _fetch_read(conn_t *, char *, size_t);
int _fetch_getln(conn_t *);
ssize_t _fetch_write(conn_t *, const char *, size_t);
ssize_t _fetch_writev(conn_t *, struct iovec *, int);
int _fetch_putln(conn_t *, const char *, size_t);
int _fetch_close(conn_t *);
int _fetch_add_entry(struct url_ent **, int *, int *,
const char *, struct url_stat *);
int _fetch_netrc_auth(struct url *url);
#define _ftp_seterr(n) _fetch_seterr(_ftp_errlist, n)
#define _http_seterr(n) _fetch_seterr(_http_errlist, n)
#define _netdb_seterr(n) _fetch_seterr(_netdb_errlist, n)
#define _url_seterr(n) _fetch_seterr(_url_errlist, n)
#ifndef NDEBUG
#define DEBUG(x) do { if (fetchDebug) { x; } } while (0)
#else
#define DEBUG(x) do { } while (0)
#endif
/*
* I don't really like exporting _http_request() and _ftp_request(),
* but the HTTP and FTP code occasionally needs to cross-call
* eachother, and this saves me from adding a lot of special-case code
* to handle those cases.
*
* Note that _*_request() free purl, which is way ugly but saves us a
* whole lot of trouble.
*/
#if __MOJOSETUP__
MojoInput *_http_request(struct url *, const char *,
struct url_stat *, struct url *, const char *);
MojoInput *_ftp_request(struct url *, const char *,
struct url_stat *, struct url *, const char *);
#else
FILE *_http_request(struct url *, const char *,
struct url_stat *, struct url *, const char *);
FILE *_ftp_request(struct url *, const char *,
struct url_stat *, struct url *, const char *);
#endif
/*
* Check whether a particular flag is set
*/
#define CHECK_FLAG(x) (flags && strchr(flags, (x)))
#endif

View File

@@ -1,478 +0,0 @@
/*-
* Copyright (c) 1998-2004 Dag-Erling Co<43>dan Sm<53>rgrav
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if __MOJOSETUP__
#include "mojosetup_libfetch.h"
#endif
#if !sun /* __MOJOSETUP__ Solaris support... */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libfetch/fetch.c,v 1.38 2004/09/21 18:35:20 des Exp $");
#endif
#include <sys/param.h>
#include <sys/errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fetch.h"
#include "common.h"
auth_t fetchAuthMethod;
int fetchLastErrCode;
char fetchLastErrString[MAXERRSTRING];
int fetchTimeout;
int fetchRestartCalls = 1;
int fetchDebug;
/*** Local data **************************************************************/
/*
* Error messages for parser errors
*/
#define URL_MALFORMED 1
#define URL_BAD_SCHEME 2
#define URL_BAD_PORT 3
static struct fetcherr _url_errlist[] = {
{ URL_MALFORMED, FETCH_URL, "Malformed URL" },
{ URL_BAD_SCHEME, FETCH_URL, "Invalid URL scheme" },
{ URL_BAD_PORT, FETCH_URL, "Invalid server port" },
{ -1, FETCH_UNKNOWN, "Unknown parser error" }
};
/*** Public API **************************************************************/
/*
* Select the appropriate protocol for the URL scheme, and return a
* read-only stream connected to the document referenced by the URL.
* Also fill out the struct url_stat.
*/
#if __MOJOSETUP__
MojoInput *
#else
FILE *
#endif
fetchXGet(struct url *URL, struct url_stat *us, const char *flags)
{
int direct;
direct = CHECK_FLAG('d');
if (us != NULL) {
us->size = -1;
us->atime = us->mtime = 0;
}
#if __MOJOSETUP__
#if SUPPORT_URL_FTP
if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
return (fetchXGetFTP(URL, us, flags));
#endif
#if SUPPORT_URL_HTTP
if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
return (fetchXGetHTTP(URL, us, flags));
#endif
#if SUPPORT_URL_HTTPS
if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
return (fetchXGetHTTP(URL, us, flags));
#endif
#else
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
return (fetchXGetFile(URL, us, flags));
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
return (fetchXGetFTP(URL, us, flags));
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
return (fetchXGetHTTP(URL, us, flags));
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
return (fetchXGetHTTP(URL, us, flags));
#endif
_url_seterr(URL_BAD_SCHEME);
return (NULL);
}
/*
* Select the appropriate protocol for the URL scheme, and return a
* read-only stream connected to the document referenced by the URL.
*/
#if !__MOJOSETUP__
FILE *
fetchGet(struct url *URL, const char *flags)
{
return (fetchXGet(URL, NULL, flags));
}
/*
* Select the appropriate protocol for the URL scheme, and return a
* write-only stream connected to the document referenced by the URL.
*/
FILE *
fetchPut(struct url *URL, const char *flags)
{
int direct;
direct = CHECK_FLAG('d');
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
return (fetchPutFile(URL, flags));
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
return (fetchPutFTP(URL, flags));
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
return (fetchPutHTTP(URL, flags));
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
return (fetchPutHTTP(URL, flags));
_url_seterr(URL_BAD_SCHEME);
return (NULL);
}
/*
* Select the appropriate protocol for the URL scheme, and return the
* size of the document referenced by the URL if it exists.
*/
int
fetchStat(struct url *URL, struct url_stat *us, const char *flags)
{
int direct;
direct = CHECK_FLAG('d');
if (us != NULL) {
us->size = -1;
us->atime = us->mtime = 0;
}
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
return (fetchStatFile(URL, us, flags));
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
return (fetchStatFTP(URL, us, flags));
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
return (fetchStatHTTP(URL, us, flags));
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
return (fetchStatHTTP(URL, us, flags));
_url_seterr(URL_BAD_SCHEME);
return (-1);
}
/*
* Select the appropriate protocol for the URL scheme, and return a
* list of files in the directory pointed to by the URL.
*/
struct url_ent *
fetchList(struct url *URL, const char *flags)
{
int direct;
direct = CHECK_FLAG('d');
if (strcasecmp(URL->scheme, SCHEME_FILE) == 0)
return (fetchListFile(URL, flags));
else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0)
return (fetchListFTP(URL, flags));
else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0)
return (fetchListHTTP(URL, flags));
else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0)
return (fetchListHTTP(URL, flags));
_url_seterr(URL_BAD_SCHEME);
return (NULL);
}
#endif
/*
* Attempt to parse the given URL; if successful, call fetchXGet().
*/
#if __MOJOSETUP__
MojoInput *
#else
FILE *
#endif
fetchXGetURL(const char *URL, struct url_stat *us, const char *flags)
{
struct url *u;
#if __MOJOSETUP__
MojoInput *f = NULL;
#else
FILE *f;
#endif
if ((u = fetchParseURL(URL)) == NULL)
return (NULL);
f = fetchXGet(u, us, flags);
fetchFreeURL(u);
return (f);
}
/*
* Attempt to parse the given URL; if successful, call fetchGet().
*/
#if !__MOJOSETUP__
FILE *
fetchGetURL(const char *URL, const char *flags)
{
return (fetchXGetURL(URL, NULL, flags));
}
/*
* Attempt to parse the given URL; if successful, call fetchPut().
*/
FILE *
fetchPutURL(const char *URL, const char *flags)
{
struct url *u;
FILE *f;
if ((u = fetchParseURL(URL)) == NULL)
return (NULL);
f = fetchPut(u, flags);
fetchFreeURL(u);
return (f);
}
/*
* Attempt to parse the given URL; if successful, call fetchStat().
*/
int
fetchStatURL(const char *URL, struct url_stat *us, const char *flags)
{
struct url *u;
int s;
if ((u = fetchParseURL(URL)) == NULL)
return (-1);
s = fetchStat(u, us, flags);
fetchFreeURL(u);
return (s);
}
/*
* Attempt to parse the given URL; if successful, call fetchList().
*/
struct url_ent *
fetchListURL(const char *URL, const char *flags)
{
struct url *u;
struct url_ent *ue;
if ((u = fetchParseURL(URL)) == NULL)
return (NULL);
ue = fetchList(u, flags);
fetchFreeURL(u);
return (ue);
}
#endif
/*
* Make a URL
*/
struct url *
fetchMakeURL(const char *scheme, const char *host, int port, const char *doc,
const char *user, const char *pwd)
{
struct url *u;
if (!scheme || (!host && !doc)) {
_url_seterr(URL_MALFORMED);
return (NULL);
}
if (port < 0 || port > 65535) {
_url_seterr(URL_BAD_PORT);
return (NULL);
}
/* allocate struct url */
if ((u = calloc(1, sizeof(*u))) == NULL) {
_fetch_syserr();
return (NULL);
}
if ((u->doc = strdup(doc ? doc : "/")) == NULL) {
_fetch_syserr();
free(u);
return (NULL);
}
#define seturl(x) snprintf(u->x, sizeof(u->x), "%s", x)
seturl(scheme);
seturl(host);
seturl(user);
seturl(pwd);
#undef seturl
u->port = port;
return (u);
}
/*
* Split an URL into components. URL syntax is:
* [method:/][/[user[:pwd]@]host[:port]/][document]
* This almost, but not quite, RFC1738 URL syntax.
*/
struct url *
fetchParseURL(const char *URL)
{
char *doc;
const char *p, *q;
struct url *u;
int i;
/* allocate struct url */
if ((u = calloc(1, sizeof(*u))) == NULL) {
_fetch_syserr();
return (NULL);
}
/* scheme name */
if ((p = strstr(URL, ":/"))) {
snprintf(u->scheme, URL_SCHEMELEN+1,
"%.*s", (int)(p - URL), URL);
URL = ++p;
/*
* Only one slash: no host, leave slash as part of document
* Two slashes: host follows, strip slashes
*/
if (URL[1] == '/')
URL = (p += 2);
} else {
p = URL;
}
if (!*URL || *URL == '/' || *URL == '.' ||
(u->scheme[0] == '\0' &&
strchr(URL, '/') == NULL && strchr(URL, ':') == NULL))
goto nohost;
p = strpbrk(URL, "/@");
if (p && *p == '@') {
/* username */
for (q = URL, i = 0; (*q != ':') && (*q != '@'); q++)
if (i < URL_USERLEN)
u->user[i++] = *q;
/* password */
if (*q == ':')
for (q++, i = 0; (*q != ':') && (*q != '@'); q++)
if (i < URL_PWDLEN)
u->pwd[i++] = *q;
p++;
} else {
p = URL;
}
/* hostname */
#ifdef INET6
if (*p == '[' && (q = strchr(p + 1, ']')) != NULL &&
(*++q == '\0' || *q == '/' || *q == ':')) {
if ((i = q - p - 2) > MAXHOSTNAMELEN)
i = MAXHOSTNAMELEN;
strncpy(u->host, ++p, i);
p = q;
} else
#endif
for (i = 0; *p && (*p != '/') && (*p != ':'); p++)
if (i < MAXHOSTNAMELEN)
u->host[i++] = *p;
/* port */
if (*p == ':') {
for (q = ++p; *q && (*q != '/'); q++)
if (isdigit(*q))
u->port = u->port * 10 + (*q - '0');
else {
/* invalid port */
_url_seterr(URL_BAD_PORT);
goto ouch;
}
p = q;
}
nohost:
/* document */
if (!*p)
p = "/";
if (strcasecmp(u->scheme, SCHEME_HTTP) == 0 ||
strcasecmp(u->scheme, SCHEME_HTTPS) == 0) {
const char hexnums[] = "0123456789abcdef";
/* percent-escape whitespace. */
if ((doc = malloc(strlen(p) * 3 + 1)) == NULL) {
_fetch_syserr();
goto ouch;
}
u->doc = doc;
while (*p != '\0') {
if (!isspace(*p)) {
*doc++ = *p++;
} else {
*doc++ = '%';
*doc++ = hexnums[((unsigned int)*p) >> 4];
*doc++ = hexnums[((unsigned int)*p) & 0xf];
p++;
}
}
*doc = '\0';
} else if ((u->doc = strdup(p)) == NULL) {
_fetch_syserr();
goto ouch;
}
DEBUG(fprintf(stderr,
"scheme: [%s]\n"
"user: [%s]\n"
"password: [%s]\n"
"host: [%s]\n"
"port: [%d]\n"
"document: [%s]\n",
u->scheme, u->user, u->pwd,
u->host, u->port, u->doc));
return (u);
ouch:
free(u);
return (NULL);
}
/*
* Free a URL
*/
void
fetchFreeURL(struct url *u)
{
free(u->doc);
free(u);
}

View File

@@ -1,184 +0,0 @@
/*-
* Copyright (c) 1998-2004 Dag-Erling Co<43>dan Sm<53>rgrav
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/lib/libfetch/fetch.h,v 1.26 2004/09/21 18:35:20 des Exp $
*/
#ifndef _FETCH_H_INCLUDED
#define _FETCH_H_INCLUDED
#if __MOJOSETUP__
#define _LIBFETCH_VER3(ver) "libfetch/2.0 (MojoSetup " #ver ")"
#define _LIBFETCH_VER2(ver) _LIBFETCH_VER3(ver)
#define _LIBFETCH_VER _LIBFETCH_VER2(APPREV)
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
#ifndef __BEGIN_DECLS
#define __BEGIN_DECLS
#endif
#ifndef __END_DECLS
#define __END_DECLS
#endif
#else
#define _LIBFETCH_VER "libfetch/2.0"
#endif
#define URL_SCHEMELEN 16
#define URL_USERLEN 256
#define URL_PWDLEN 256
struct url {
char scheme[URL_SCHEMELEN+1];
char user[URL_USERLEN+1];
char pwd[URL_PWDLEN+1];
char host[MAXHOSTNAMELEN+1];
int port;
char *doc;
off_t offset;
size_t length;
};
struct url_stat {
off_t size;
time_t atime;
time_t mtime;
};
struct url_ent {
char name[PATH_MAX];
struct url_stat stat;
};
/* Recognized schemes */
#define SCHEME_FTP "ftp"
#define SCHEME_HTTP "http"
#define SCHEME_HTTPS "https"
#define SCHEME_FILE "file"
/* Error codes */
#define FETCH_ABORT 1
#define FETCH_AUTH 2
#define FETCH_DOWN 3
#define FETCH_EXISTS 4
#define FETCH_FULL 5
#define FETCH_INFO 6
#define FETCH_MEMORY 7
#define FETCH_MOVED 8
#define FETCH_NETWORK 9
#define FETCH_OK 10
#define FETCH_PROTO 11
#define FETCH_RESOLV 12
#define FETCH_SERVER 13
#define FETCH_TEMP 14
#define FETCH_TIMEOUT 15
#define FETCH_UNAVAIL 16
#define FETCH_UNKNOWN 17
#define FETCH_URL 18
#define FETCH_VERBOSE 19
__BEGIN_DECLS
/* FILE-specific functions */
#if !__MOJOSETUP__
FILE *fetchXGetFile(struct url *, struct url_stat *, const char *);
FILE *fetchGetFile(struct url *, const char *);
FILE *fetchPutFile(struct url *, const char *);
int fetchStatFile(struct url *, struct url_stat *, const char *);
struct url_ent *fetchListFile(struct url *, const char *);
#endif
/* HTTP-specific functions */
#if __MOJOSETUP__
MojoInput *fetchXGetHTTP(struct url *, struct url_stat *, const char *);
#else
FILE *fetchXGetHTTP(struct url *, struct url_stat *, const char *);
FILE *fetchGetHTTP(struct url *, const char *);
FILE *fetchPutHTTP(struct url *, const char *);
int fetchStatHTTP(struct url *, struct url_stat *, const char *);
struct url_ent *fetchListHTTP(struct url *, const char *);
#endif
/* FTP-specific functions */
#if __MOJOSETUP__
MojoInput *fetchXGetFTP(struct url *, struct url_stat *, const char *);
#else
FILE *fetchXGetFTP(struct url *, struct url_stat *, const char *);
FILE *fetchGetFTP(struct url *, const char *);
FILE *fetchPutFTP(struct url *, const char *);
int fetchStatFTP(struct url *, struct url_stat *, const char *);
struct url_ent *fetchListFTP(struct url *, const char *);
#endif
/* Generic functions */
#if __MOJOSETUP__
MojoInput *fetchXGetURL(const char *, struct url_stat *, const char *);
#else
FILE *fetchXGetURL(const char *, struct url_stat *, const char *);
FILE *fetchGetURL(const char *, const char *);
FILE *fetchPutURL(const char *, const char *);
int fetchStatURL(const char *, struct url_stat *, const char *);
struct url_ent *fetchListURL(const char *, const char *);
#endif
#if __MOJOSETUP__
MojoInput *fetchXGet(struct url *, struct url_stat *, const char *);
#else
FILE *fetchXGet(struct url *, struct url_stat *, const char *);
FILE *fetchGet(struct url *, const char *);
FILE *fetchPut(struct url *, const char *);
int fetchStat(struct url *, struct url_stat *, const char *);
struct url_ent *fetchList(struct url *, const char *);
#endif
/* URL parsing */
struct url *fetchMakeURL(const char *, const char *, int,
const char *, const char *, const char *);
struct url *fetchParseURL(const char *);
void fetchFreeURL(struct url *);
__END_DECLS
/* Authentication */
typedef int (*auth_t)(struct url *);
extern auth_t fetchAuthMethod;
/* Last error code */
extern int fetchLastErrCode;
#define MAXERRSTRING 256
extern char fetchLastErrString[MAXERRSTRING];
/* I/O timeout */
extern int fetchTimeout;
/* Restart interrupted syscalls */
extern int fetchRestartCalls;
/* Extra verbosity */
extern int fetchDebug;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,47 +0,0 @@
# $FreeBSD: src/lib/libfetch/ftp.errors,v 1.6 2002/10/30 06:06:16 des Exp $
#
# This list is taken from RFC 959.
# It probably needs a going over.
#
110 OK Restart marker reply
120 TEMP Service ready in a few minutes
125 OK Data connection already open; transfer starting
150 OK File status okay; about to open data connection
200 OK Command okay
202 PROTO Command not implemented, superfluous at this site
211 INFO System status, or system help reply
212 INFO Directory status
213 INFO File status
214 INFO Help message
215 INFO Set system type
220 OK Service ready for new user
221 OK Service closing control connection
225 OK Data connection open; no transfer in progress
226 OK Requested file action successful
227 OK Entering Passive Mode
229 OK Entering Extended Passive Mode
230 OK User logged in, proceed
250 OK Requested file action okay, completed
257 OK File/directory created
331 AUTH User name okay, need password
332 AUTH Need account for login
350 OK Requested file action pending further information
421 DOWN Service not available, closing control connection
425 NETWORK Can't open data connection
426 ABORT Connection closed; transfer aborted
450 UNAVAIL File unavailable (e.g., file busy)
451 SERVER Requested action aborted: local error in processing
452 FULL Insufficient storage space in system
500 PROTO Syntax error, command unrecognized
501 PROTO Syntax error in parameters or arguments
502 PROTO Command not implemented
503 PROTO Bad sequence of commands
504 PROTO Command not implemented for that parameter
530 AUTH Not logged in
532 AUTH Need account for storing files
535 PROTO Bug in MediaHawk Video Kernel FTP server
550 UNAVAIL File unavailable (e.g., file not found, no access)
551 PROTO Requested action aborted. Page type unknown
552 FULL Exceeded storage allocation
553 EXISTS File name not allowed
999 PROTO Protocol error

View File

@@ -1,70 +0,0 @@
/*
Copyright (c) 2006-2010 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>
*/
static struct fetcherr _ftp_errlist[] = {
{ 110, FETCH_OK, "Restart marker reply" },
{ 120, FETCH_TEMP, "Service ready in a few minutes" },
{ 125, FETCH_OK, "Data connection already open; transfer starting" },
{ 150, FETCH_OK, "File status okay; about to open data connection" },
{ 200, FETCH_OK, "Command okay" },
{ 202, FETCH_PROTO, "Command not implemented, superfluous at this site" },
{ 211, FETCH_INFO, "System status, or system help reply" },
{ 212, FETCH_INFO, "Directory status" },
{ 213, FETCH_INFO, "File status" },
{ 214, FETCH_INFO, "Help message" },
{ 215, FETCH_INFO, "Set system type" },
{ 220, FETCH_OK, "Service ready for new user" },
{ 221, FETCH_OK, "Service closing control connection" },
{ 225, FETCH_OK, "Data connection open; no transfer in progress" },
{ 226, FETCH_OK, "Requested file action successful" },
{ 227, FETCH_OK, "Entering Passive Mode" },
{ 229, FETCH_OK, "Entering Extended Passive Mode" },
{ 230, FETCH_OK, "User logged in, proceed" },
{ 250, FETCH_OK, "Requested file action okay, completed" },
{ 257, FETCH_OK, "File/directory created" },
{ 331, FETCH_AUTH, "User name okay, need password" },
{ 332, FETCH_AUTH, "Need account for login" },
{ 350, FETCH_OK, "Requested file action pending further information" },
{ 421, FETCH_DOWN, "Service not available, closing control connection" },
{ 425, FETCH_NETWORK, "Can't open data connection" },
{ 426, FETCH_ABORT, "Connection closed; transfer aborted" },
{ 450, FETCH_UNAVAIL, "File unavailable (e.g., file busy)" },
{ 451, FETCH_SERVER, "Requested action aborted: local error in processing" },
{ 452, FETCH_FULL, "Insufficient storage space in system" },
{ 500, FETCH_PROTO, "Syntax error, command unrecognized" },
{ 501, FETCH_PROTO, "Syntax error in parameters or arguments" },
{ 502, FETCH_PROTO, "Command not implemented" },
{ 503, FETCH_PROTO, "Bad sequence of commands" },
{ 504, FETCH_PROTO, "Command not implemented for that parameter" },
{ 530, FETCH_AUTH, "Not logged in" },
{ 532, FETCH_AUTH, "Need account for storing files" },
{ 535, FETCH_PROTO, "Bug in MediaHawk Video Kernel FTP server" },
{ 550, FETCH_UNAVAIL, "File unavailable (e.g., file not found, no access)" },
{ 551, FETCH_PROTO, "Requested action aborted. Page type unknown" },
{ 552, FETCH_FULL, "Exceeded storage allocation" },
{ 553, FETCH_EXISTS, "File name not allowed" },
{ 999, FETCH_PROTO, "Protocol error" },
{ -1, FETCH_UNKNOWN, "Unknown FTP error" }
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,45 +0,0 @@
# $FreeBSD: src/lib/libfetch/http.errors,v 1.5 2001/05/23 18:52:02 des Exp $
#
# This list is taken from RFC 2068.
#
100 OK Continue
101 OK Switching Protocols
200 OK OK
201 OK Created
202 OK Accepted
203 INFO Non-Authoritative Information
204 OK No Content
205 OK Reset Content
206 OK Partial Content
300 MOVED Multiple Choices
301 MOVED Moved Permanently
302 MOVED Moved Temporarily
303 MOVED See Other
304 OK Not Modified
305 INFO Use Proxy
307 MOVED Temporary Redirect
400 PROTO Bad Request
401 AUTH Unauthorized
402 AUTH Payment Required
403 AUTH Forbidden
404 UNAVAIL Not Found
405 PROTO Method Not Allowed
406 PROTO Not Acceptable
407 AUTH Proxy Authentication Required
408 TIMEOUT Request Time-out
409 EXISTS Conflict
410 UNAVAIL Gone
411 PROTO Length Required
412 SERVER Precondition Failed
413 PROTO Request Entity Too Large
414 PROTO Request-URI Too Large
415 PROTO Unsupported Media Type
416 UNAVAIL Requested Range Not Satisfiable
417 SERVER Expectation Failed
500 SERVER Internal Server Error
501 PROTO Not Implemented
502 SERVER Bad Gateway
503 TEMP Service Unavailable
504 TIMEOUT Gateway Time-out
505 PROTO HTTP Version not supported
999 PROTO Protocol error

View File

@@ -1,68 +0,0 @@
/*
Copyright (c) 2006-2010 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>
*/
static struct fetcherr _http_errlist[] = {
{ 100, FETCH_OK, "Continue" },
{ 101, FETCH_OK, "Switching Protocols" },
{ 200, FETCH_OK, "OK" },
{ 201, FETCH_OK, "Created" },
{ 202, FETCH_OK, "Accepted" },
{ 203, FETCH_INFO, "Non-Authoritative Information" },
{ 204, FETCH_OK, "No Content" },
{ 205, FETCH_OK, "Reset Content" },
{ 206, FETCH_OK, "Partial Content" },
{ 300, FETCH_MOVED, "Multiple Choices" },
{ 301, FETCH_MOVED, "Moved Permanently" },
{ 302, FETCH_MOVED, "Moved Temporarily" },
{ 303, FETCH_MOVED, "See Other" },
{ 304, FETCH_OK, "Not Modified" },
{ 305, FETCH_INFO, "Use Proxy" },
{ 307, FETCH_MOVED, "Temporary Redirect" },
{ 400, FETCH_PROTO, "Bad Request" },
{ 401, FETCH_AUTH, "Unauthorized" },
{ 402, FETCH_AUTH, "Payment Required" },
{ 403, FETCH_AUTH, "Forbidden" },
{ 404, FETCH_UNAVAIL, "Not Found" },
{ 405, FETCH_PROTO, "Method Not Allowed" },
{ 406, FETCH_PROTO, "Not Acceptable" },
{ 407, FETCH_AUTH, "Proxy Authentication Required" },
{ 408, FETCH_TIMEOUT, "Request Time-out" },
{ 409, FETCH_EXISTS, "Conflict" },
{ 410, FETCH_UNAVAIL, "Gone" },
{ 411, FETCH_PROTO, "Length Required" },
{ 412, FETCH_SERVER, "Precondition Failed" },
{ 413, FETCH_PROTO, "Request Entity Too Large" },
{ 414, FETCH_PROTO, "Request-URI Too Large" },
{ 415, FETCH_PROTO, "Unsupported Media Type" },
{ 416, FETCH_UNAVAIL, "Requested Range Not Satisfiable" },
{ 417, FETCH_SERVER, "Expectation Failed" },
{ 500, FETCH_SERVER, "Internal Server Error" },
{ 501, FETCH_PROTO, "Not Implemented" },
{ 502, FETCH_SERVER, "Bad Gateway" },
{ 503, FETCH_TEMP, "Service Unavailable" },
{ 504, FETCH_TIMEOUT, "Gateway Time-out" },
{ 505, FETCH_PROTO, "HTTP Version not supported" },
{ 999, FETCH_PROTO, "Protocol error" },
{ -1, FETCH_UNKNOWN, "Unknown HTTP error" }
};

View File

@@ -1,113 +0,0 @@
/*
Copyright (c) 2006-2010 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>
*/
#ifndef _INCL_MOJOSETUP_LIBFETCH_H_
#define _INCL_MOJOSETUP_LIBFETCH_H_
#include "../universal.h"
#include "../platform.h"
#include "../fileio.h"
#include <stdarg.h>
#include <stdint.h>
#include <time.h>
#include <limits.h>
#include <sys/stat.h>
#if sun
#ifdef u_int32_t
#undef u_int32_t
#endif
#define u_int32_t uint32_t
#endif
int MOJOSETUP_vasprintf(char **strp, const char *fmt, va_list ap);
#define vasprintf MOJOSETUP_vasprintf
int MOJOSETUP_asprintf(char **strp, const char *fmt, ...) ISPRINTF(2,3);
#define asprintf MOJOSETUP_asprintf
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
#ifndef FREEBSD
#define FREEBSD 1
#endif
#endif
// Things FreeBSD defines elsewhere...
#ifndef __FBSDID
#define __FBSDID(x)
#endif
#ifndef __DECONST
#define __DECONST(type, var) ((type) var)
#endif
#ifndef __unused
#define __unused
#endif
// apparently this is 17 in FreeBSD.
#ifndef MAXLOGNAME
#define MAXLOGNAME (17)
#endif
#undef calloc
#define calloc(x, y) xmalloc(x * y)
#undef malloc
#define malloc(x) xmalloc(x)
#undef realloc
#define realloc(x, y) xrealloc(x, y)
#undef strdup
#define strdup(x) xstrdup(x)
#undef strncpy
#define strncpy(x, y, z) xstrncpy(x, y, z)
#if !FREEBSD
#ifndef TCP_NOPUSH
#define TCP_NOPUSH TCP_CORK
#endif
#define EAUTH EPERM
boolean ishexnumber(char ch);
// Linux has had this since glibc 4.6.8, but doesn't expose it in the headers
// without _XOPEN_SOURCE or _GNU_SOURCE, which breaks other things.
// ...just force a declaration here, then.
#ifdef __linux__
char *strptime(const char *s, const char *format, struct tm *tm);
#endif
#endif
time_t timegm_portable(struct tm *tm);
#ifdef timegm
#undef timegm
#endif
#define timegm timegm_portable
#endif
// end of mojosetup_libfetch.h ...

View File

@@ -1,13 +0,0 @@
This is the source code to liblzma from XZ Utils:
http://tukaani.org/xz/
This is a snapshot of the xz-5.0.3 release. Changes I've made to it are
wrapped in #if __MOJOSETUP__ blocks. I've tried to agressively delete files
we don't use at all, too.
The source code in this directory is public domain.
--ryan.

View File

@@ -1,318 +0,0 @@
/**
* \file api/lzma.h
* \brief The public API of liblzma data compression library
*
* liblzma is a public domain general-purpose data compression library with
* a zlib-like API. The native file format is .xz, but also the old .lzma
* format and raw (no headers) streams are supported. Multiple compression
* algorithms (filters) are supported. Currently LZMA2 is the primary filter.
*
* liblzma is part of XZ Utils <http://tukaani.org/xz/>. XZ Utils includes
* a gzip-like command line tool named xz and some other tools. XZ Utils
* is developed and maintained by Lasse Collin.
*
* Major parts of liblzma are based on Igor Pavlov's public domain LZMA SDK
* <http://7-zip.org/sdk.html>.
*
* The SHA-256 implementation is based on the public domain code found from
* 7-Zip <http://7-zip.org/>, which has a modified version of the public
* domain SHA-256 code found from Crypto++ <http://www.cryptopp.com/>.
* The SHA-256 code in Crypto++ was written by Kevin Springle and Wei Dai.
*/
/*
//
// Copyright 2012 Lasse Collin
// Public Domain
//
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*/
#ifndef LZMA_H
#define LZMA_H
/*****************************
* Required standard headers *
*****************************/
/*
* liblzma API headers need some standard types and macros. To allow
* including lzma.h without requiring the application to include other
* headers first, lzma.h includes the required standard headers unless
* they already seem to be included already or if LZMA_MANUAL_HEADERS
* has been defined.
*
* Here's what types and macros are needed and from which headers:
* - stddef.h: size_t, NULL
* - stdint.h: uint8_t, uint32_t, uint64_t, UINT32_C(n), uint64_C(n),
* UINT32_MAX, UINT64_MAX
*
* However, inttypes.h is a little more portable than stdint.h, although
* inttypes.h declares some unneeded things compared to plain stdint.h.
*
* The hacks below aren't perfect, specifically they assume that inttypes.h
* exists and that it typedefs at least uint8_t, uint32_t, and uint64_t,
* and that, in case of incomplete inttypes.h, unsigned int is 32-bit.
* If the application already takes care of setting up all the types and
* macros properly (for example by using gnulib's stdint.h or inttypes.h),
* we try to detect that the macros are already defined and don't include
* inttypes.h here again. However, you may define LZMA_MANUAL_HEADERS to
* force this file to never include any system headers.
*
* Some could argue that liblzma API should provide all the required types,
* for example lzma_uint64, LZMA_UINT64_C(n), and LZMA_UINT64_MAX. This was
* seen as an unnecessary mess, since most systems already provide all the
* necessary types and macros in the standard headers.
*
* Note that liblzma API still has lzma_bool, because using stdbool.h would
* break C89 and C++ programs on many systems. sizeof(bool) in C99 isn't
* necessarily the same as sizeof(bool) in C++.
*/
#ifndef LZMA_MANUAL_HEADERS
/*
* I suppose this works portably also in C++. Note that in C++,
* we need to get size_t into the global namespace.
*/
# include <stddef.h>
/*
* Skip inttypes.h if we already have all the required macros. If we
* have the macros, we assume that we have the matching typedefs too.
*/
# if !defined(UINT32_C) || !defined(UINT64_C) \
|| !defined(UINT32_MAX) || !defined(UINT64_MAX)
/*
* MSVC has no C99 support, and thus it cannot be used to
* compile liblzma. The liblzma API has to still be usable
* from MSVC, so we need to define the required standard
* integer types here.
*/
# if defined(_WIN32) && defined(_MSC_VER)
typedef unsigned __int8 uint8_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
# else
/* Use the standard inttypes.h. */
# ifdef __cplusplus
/*
* C99 sections 7.18.2 and 7.18.4 specify
* that C++ implementations define the limit
* and constant macros only if specifically
* requested. Note that if you want the
* format macros (PRIu64 etc.) too, you need
* to define __STDC_FORMAT_MACROS before
* including lzma.h, since re-including
* inttypes.h with __STDC_FORMAT_MACROS
* defined doesn't necessarily work.
*/
# ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS 1
# endif
# ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS 1
# endif
# endif
# include <inttypes.h>
# endif
/*
* Some old systems have only the typedefs in inttypes.h, and
* lack all the macros. For those systems, we need a few more
* hacks. We assume that unsigned int is 32-bit and unsigned
* long is either 32-bit or 64-bit. If these hacks aren't
* enough, the application has to setup the types manually
* before including lzma.h.
*/
# ifndef UINT32_C
# if defined(_WIN32) && defined(_MSC_VER)
# define UINT32_C(n) n ## UI32
# else
# define UINT32_C(n) n ## U
# endif
# endif
# ifndef UINT64_C
# if defined(_WIN32) && defined(_MSC_VER)
# define UINT64_C(n) n ## UI64
# else
/* Get ULONG_MAX. */
# include <limits.h>
# if ULONG_MAX == 4294967295UL
# define UINT64_C(n) n ## ULL
# else
# define UINT64_C(n) n ## UL
# endif
# endif
# endif
# ifndef UINT32_MAX
# define UINT32_MAX (UINT32_C(4294967295))
# endif
# ifndef UINT64_MAX
# define UINT64_MAX (UINT64_C(18446744073709551615))
# endif
# endif
#endif /* ifdef LZMA_MANUAL_HEADERS */
/******************
* LZMA_API macro *
******************/
/*
* Some systems require that the functions and function pointers are
* declared specially in the headers. LZMA_API_IMPORT is for importing
* symbols and LZMA_API_CALL is to specify the calling convention.
*
* By default it is assumed that the application will link dynamically
* against liblzma. #define LZMA_API_STATIC in your application if you
* want to link against static liblzma. If you don't care about portability
* to operating systems like Windows, or at least don't care about linking
* against static liblzma on them, don't worry about LZMA_API_STATIC. That
* is, most developers will never need to use LZMA_API_STATIC.
*
* The GCC variants are a special case on Windows (Cygwin and MinGW).
* We rely on GCC doing the right thing with its auto-import feature,
* and thus don't use __declspec(dllimport). This way developers don't
* need to worry about LZMA_API_STATIC. Also the calling convention is
* omitted on Cygwin but not on MinGW.
*/
#ifndef LZMA_API_IMPORT
# if !defined(LZMA_API_STATIC) && defined(_WIN32) && !defined(__GNUC__)
# define LZMA_API_IMPORT __declspec(dllimport)
# else
# define LZMA_API_IMPORT
# endif
#endif
#ifndef LZMA_API_CALL
# if defined(_WIN32) && !defined(__CYGWIN__)
# define LZMA_API_CALL __cdecl
# else
# define LZMA_API_CALL
# endif
#endif
#ifndef LZMA_API
# define LZMA_API(type) LZMA_API_IMPORT type LZMA_API_CALL
#endif
/***********
* nothrow *
***********/
/*
* None of the functions in liblzma may throw an exception. Even
* the functions that use callback functions won't throw exceptions,
* because liblzma would break if a callback function threw an exception.
*/
#ifndef lzma_nothrow
# if defined(__cplusplus)
# define lzma_nothrow throw()
# elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
# define lzma_nothrow __attribute__((__nothrow__))
# else
# define lzma_nothrow
# endif
#endif
/********************
* GNU C extensions *
********************/
/*
* GNU C extensions are used conditionally in the public API. It doesn't
* break anything if these are sometimes enabled and sometimes not, only
* affects warnings and optimizations.
*/
#if __GNUC__ >= 3
# ifndef lzma_attribute
# define lzma_attribute(attr) __attribute__(attr)
# endif
/* warn_unused_result was added in GCC 3.4. */
# ifndef lzma_attr_warn_unused_result
# if __GNUC__ == 3 && __GNUC_MINOR__ < 4
# define lzma_attr_warn_unused_result
# endif
# endif
#else
# ifndef lzma_attribute
# define lzma_attribute(attr)
# endif
#endif
#ifndef lzma_attr_pure
# define lzma_attr_pure lzma_attribute((__pure__))
#endif
#ifndef lzma_attr_const
# define lzma_attr_const lzma_attribute((__const__))
#endif
#ifndef lzma_attr_warn_unused_result
# define lzma_attr_warn_unused_result \
lzma_attribute((__warn_unused_result__))
#endif
/**************
* Subheaders *
**************/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Subheaders check that this is defined. It is to prevent including
* them directly from applications.
*/
#define LZMA_H_INTERNAL 1
/* Basic features */
#include "lzma/version.h"
#include "lzma/base.h"
#include "lzma/vli.h"
#include "lzma/check.h"
/* Filters */
#include "lzma/filter.h"
#include "lzma/bcj.h"
#include "lzma/delta.h"
#include "lzma/lzma.h"
/* Container formats */
#include "lzma/container.h"
/* Advanced features */
#include "lzma/stream_flags.h"
#include "lzma/block.h"
#include "lzma/index.h"
#include "lzma/index_hash.h"
/* Hardware information */
#include "lzma/hardware.h"
/*
* All subheaders included. Undefine LZMA_H_INTERNAL to prevent applications
* re-including the subheaders.
*/
#undef LZMA_H_INTERNAL
#ifdef __cplusplus
}
#endif
#endif /* ifndef LZMA_H */

View File

@@ -1,606 +0,0 @@
/**
* \file lzma/base.h
* \brief Data types and functions used in many places in liblzma API
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Boolean
*
* This is here because C89 doesn't have stdbool.h. To set a value for
* variables having type lzma_bool, you can use
* - C99's `true' and `false' from stdbool.h;
* - C++'s internal `true' and `false'; or
* - integers one (true) and zero (false).
*/
typedef unsigned char lzma_bool;
/**
* \brief Type of reserved enumeration variable in structures
*
* To avoid breaking library ABI when new features are added, several
* structures contain extra variables that may be used in future. Since
* sizeof(enum) can be different than sizeof(int), and sizeof(enum) may
* even vary depending on the range of enumeration constants, we specify
* a separate type to be used for reserved enumeration variables. All
* enumeration constants in liblzma API will be non-negative and less
* than 128, which should guarantee that the ABI won't break even when
* new constants are added to existing enumerations.
*/
typedef enum {
LZMA_RESERVED_ENUM = 0
} lzma_reserved_enum;
/**
* \brief Return values used by several functions in liblzma
*
* Check the descriptions of specific functions to find out which return
* values they can return. With some functions the return values may have
* more specific meanings than described here; those differences are
* described per-function basis.
*/
typedef enum {
LZMA_OK = 0,
/**<
* \brief Operation completed successfully
*/
LZMA_STREAM_END = 1,
/**<
* \brief End of stream was reached
*
* In encoder, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or
* LZMA_FINISH was finished. In decoder, this indicates
* that all the data was successfully decoded.
*
* In all cases, when LZMA_STREAM_END is returned, the last
* output bytes should be picked from strm->next_out.
*/
LZMA_NO_CHECK = 2,
/**<
* \brief Input stream has no integrity check
*
* This return value can be returned only if the
* LZMA_TELL_NO_CHECK flag was used when initializing
* the decoder. LZMA_NO_CHECK is just a warning, and
* the decoding can be continued normally.
*
* It is possible to call lzma_get_check() immediately after
* lzma_code has returned LZMA_NO_CHECK. The result will
* naturally be LZMA_CHECK_NONE, but the possibility to call
* lzma_get_check() may be convenient in some applications.
*/
LZMA_UNSUPPORTED_CHECK = 3,
/**<
* \brief Cannot calculate the integrity check
*
* The usage of this return value is different in encoders
* and decoders.
*
* Encoders can return this value only from the initialization
* function. If initialization fails with this value, the
* encoding cannot be done, because there's no way to produce
* output with the correct integrity check.
*
* Decoders can return this value only from lzma_code() and
* only if the LZMA_TELL_UNSUPPORTED_CHECK flag was used when
* initializing the decoder. The decoding can still be
* continued normally even if the check type is unsupported,
* but naturally the check will not be validated, and possible
* errors may go undetected.
*
* With decoder, it is possible to call lzma_get_check()
* immediately after lzma_code() has returned
* LZMA_UNSUPPORTED_CHECK. This way it is possible to find
* out what the unsupported Check ID was.
*/
LZMA_GET_CHECK = 4,
/**<
* \brief Integrity check type is now available
*
* This value can be returned only by the lzma_code() function
* and only if the decoder was initialized with the
* LZMA_TELL_ANY_CHECK flag. LZMA_GET_CHECK tells the
* application that it may now call lzma_get_check() to find
* out the Check ID. This can be used, for example, to
* implement a decoder that accepts only files that have
* strong enough integrity check.
*/
LZMA_MEM_ERROR = 5,
/**<
* \brief Cannot allocate memory
*
* Memory allocation failed, or the size of the allocation
* would be greater than SIZE_MAX.
*
* Due to internal implementation reasons, the coding cannot
* be continued even if more memory were made available after
* LZMA_MEM_ERROR.
*/
LZMA_MEMLIMIT_ERROR = 6,
/**
* \brief Memory usage limit was reached
*
* Decoder would need more memory than allowed by the
* specified memory usage limit. To continue decoding,
* the memory usage limit has to be increased with
* lzma_memlimit_set().
*/
LZMA_FORMAT_ERROR = 7,
/**<
* \brief File format not recognized
*
* The decoder did not recognize the input as supported file
* format. This error can occur, for example, when trying to
* decode .lzma format file with lzma_stream_decoder,
* because lzma_stream_decoder accepts only the .xz format.
*/
LZMA_OPTIONS_ERROR = 8,
/**<
* \brief Invalid or unsupported options
*
* Invalid or unsupported options, for example
* - unsupported filter(s) or filter options; or
* - reserved bits set in headers (decoder only).
*
* Rebuilding liblzma with more features enabled, or
* upgrading to a newer version of liblzma may help.
*/
LZMA_DATA_ERROR = 9,
/**<
* \brief Data is corrupt
*
* The usage of this return value is different in encoders
* and decoders. In both encoder and decoder, the coding
* cannot continue after this error.
*
* Encoders return this if size limits of the target file
* format would be exceeded. These limits are huge, thus
* getting this error from an encoder is mostly theoretical.
* For example, the maximum compressed and uncompressed
* size of a .xz Stream is roughly 8 EiB (2^63 bytes).
*
* Decoders return this error if the input data is corrupt.
* This can mean, for example, invalid CRC32 in headers
* or invalid check of uncompressed data.
*/
LZMA_BUF_ERROR = 10,
/**<
* \brief No progress is possible
*
* This error code is returned when the coder cannot consume
* any new input and produce any new output. The most common
* reason for this error is that the input stream being
* decoded is truncated or corrupt.
*
* This error is not fatal. Coding can be continued normally
* by providing more input and/or more output space, if
* possible.
*
* Typically the first call to lzma_code() that can do no
* progress returns LZMA_OK instead of LZMA_BUF_ERROR. Only
* the second consecutive call doing no progress will return
* LZMA_BUF_ERROR. This is intentional.
*
* With zlib, Z_BUF_ERROR may be returned even if the
* application is doing nothing wrong, so apps will need
* to handle Z_BUF_ERROR specially. The above hack
* guarantees that liblzma never returns LZMA_BUF_ERROR
* to properly written applications unless the input file
* is truncated or corrupt. This should simplify the
* applications a little.
*/
LZMA_PROG_ERROR = 11,
/**<
* \brief Programming error
*
* This indicates that the arguments given to the function are
* invalid or the internal state of the decoder is corrupt.
* - Function arguments are invalid or the structures
* pointed by the argument pointers are invalid
* e.g. if strm->next_out has been set to NULL and
* strm->avail_out > 0 when calling lzma_code().
* - lzma_* functions have been called in wrong order
* e.g. lzma_code() was called right after lzma_end().
* - If errors occur randomly, the reason might be flaky
* hardware.
*
* If you think that your code is correct, this error code
* can be a sign of a bug in liblzma. See the documentation
* how to report bugs.
*/
} lzma_ret;
/**
* \brief The `action' argument for lzma_code()
*
* After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or LZMA_FINISH,
* the same `action' must is used until lzma_code() returns LZMA_STREAM_END.
* Also, the amount of input (that is, strm->avail_in) must not be modified
* by the application until lzma_code() returns LZMA_STREAM_END. Changing the
* `action' or modifying the amount of input will make lzma_code() return
* LZMA_PROG_ERROR.
*/
typedef enum {
LZMA_RUN = 0,
/**<
* \brief Continue coding
*
* Encoder: Encode as much input as possible. Some internal
* buffering will probably be done (depends on the filter
* chain in use), which causes latency: the input used won't
* usually be decodeable from the output of the same
* lzma_code() call.
*
* Decoder: Decode as much input as possible and produce as
* much output as possible.
*/
LZMA_SYNC_FLUSH = 1,
/**<
* \brief Make all the input available at output
*
* Normally the encoder introduces some latency.
* LZMA_SYNC_FLUSH forces all the buffered data to be
* available at output without resetting the internal
* state of the encoder. This way it is possible to use
* compressed stream for example for communication over
* network.
*
* Only some filters support LZMA_SYNC_FLUSH. Trying to use
* LZMA_SYNC_FLUSH with filters that don't support it will
* make lzma_code() return LZMA_OPTIONS_ERROR. For example,
* LZMA1 doesn't support LZMA_SYNC_FLUSH but LZMA2 does.
*
* Using LZMA_SYNC_FLUSH very often can dramatically reduce
* the compression ratio. With some filters (for example,
* LZMA2), fine-tuning the compression options may help
* mitigate this problem significantly (for example,
* match finder with LZMA2).
*
* Decoders don't support LZMA_SYNC_FLUSH.
*/
LZMA_FULL_FLUSH = 2,
/**<
* \brief Finish encoding of the current Block
*
* All the input data going to the current Block must have
* been given to the encoder (the last bytes can still be
* pending in* next_in). Call lzma_code() with LZMA_FULL_FLUSH
* until it returns LZMA_STREAM_END. Then continue normally
* with LZMA_RUN or finish the Stream with LZMA_FINISH.
*
* This action is currently supported only by Stream encoder
* and easy encoder (which uses Stream encoder). If there is
* no unfinished Block, no empty Block is created.
*/
LZMA_FINISH = 3
/**<
* \brief Finish the coding operation
*
* All the input data must have been given to the encoder
* (the last bytes can still be pending in next_in).
* Call lzma_code() with LZMA_FINISH until it returns
* LZMA_STREAM_END. Once LZMA_FINISH has been used,
* the amount of input must no longer be changed by
* the application.
*
* When decoding, using LZMA_FINISH is optional unless the
* LZMA_CONCATENATED flag was used when the decoder was
* initialized. When LZMA_CONCATENATED was not used, the only
* effect of LZMA_FINISH is that the amount of input must not
* be changed just like in the encoder.
*/
} lzma_action;
/**
* \brief Custom functions for memory handling
*
* A pointer to lzma_allocator may be passed via lzma_stream structure
* to liblzma, and some advanced functions take a pointer to lzma_allocator
* as a separate function argument. The library will use the functions
* specified in lzma_allocator for memory handling instead of the default
* malloc() and free(). C++ users should note that the custom memory
* handling functions must not throw exceptions.
*
* liblzma doesn't make an internal copy of lzma_allocator. Thus, it is
* OK to change these function pointers in the middle of the coding
* process, but obviously it must be done carefully to make sure that the
* replacement `free' can deallocate memory allocated by the earlier
* `alloc' function(s).
*/
typedef struct {
/**
* \brief Pointer to a custom memory allocation function
*
* If you don't want a custom allocator, but still want
* custom free(), set this to NULL and liblzma will use
* the standard malloc().
*
* \param opaque lzma_allocator.opaque (see below)
* \param nmemb Number of elements like in calloc(). liblzma
* will always set nmemb to 1, so it is safe to
* ignore nmemb in a custom allocator if you like.
* The nmemb argument exists only for
* compatibility with zlib and libbzip2.
* \param size Size of an element in bytes.
* liblzma never sets this to zero.
*
* \return Pointer to the beginning of a memory block of
* `size' bytes, or NULL if allocation fails
* for some reason. When allocation fails, functions
* of liblzma return LZMA_MEM_ERROR.
*
* The allocator should not waste time zeroing the allocated buffers.
* This is not only about speed, but also memory usage, since the
* operating system kernel doesn't necessarily allocate the requested
* memory in physical memory until it is actually used. With small
* input files, liblzma may actually need only a fraction of the
* memory that it requested for allocation.
*
* \note LZMA_MEM_ERROR is also used when the size of the
* allocation would be greater than SIZE_MAX. Thus,
* don't assume that the custom allocator must have
* returned NULL if some function from liblzma
* returns LZMA_MEM_ERROR.
*/
void *(LZMA_API_CALL *alloc)(void *opaque, size_t nmemb, size_t size);
/**
* \brief Pointer to a custom memory freeing function
*
* If you don't want a custom freeing function, but still
* want a custom allocator, set this to NULL and liblzma
* will use the standard free().
*
* \param opaque lzma_allocator.opaque (see below)
* \param ptr Pointer returned by lzma_allocator.alloc(),
* or when it is set to NULL, a pointer returned
* by the standard malloc().
*/
void (LZMA_API_CALL *free)(void *opaque, void *ptr);
/**
* \brief Pointer passed to .alloc() and .free()
*
* opaque is passed as the first argument to lzma_allocator.alloc()
* and lzma_allocator.free(). This intended to ease implementing
* custom memory allocation functions for use with liblzma.
*
* If you don't need this, you should set this to NULL.
*/
void *opaque;
} lzma_allocator;
/**
* \brief Internal data structure
*
* The contents of this structure is not visible outside the library.
*/
typedef struct lzma_internal_s lzma_internal;
/**
* \brief Passing data to and from liblzma
*
* The lzma_stream structure is used for
* - passing pointers to input and output buffers to liblzma;
* - defining custom memory hander functions; and
* - holding a pointer to coder-specific internal data structures.
*
* Typical usage:
*
* - After allocating lzma_stream (on stack or with malloc()), it must be
* initialized to LZMA_STREAM_INIT (see LZMA_STREAM_INIT for details).
*
* - Initialize a coder to the lzma_stream, for example by using
* lzma_easy_encoder() or lzma_auto_decoder(). Some notes:
* - In contrast to zlib, strm->next_in and strm->next_out are
* ignored by all initialization functions, thus it is safe
* to not initialize them yet.
* - The initialization functions always set strm->total_in and
* strm->total_out to zero.
* - If the initialization function fails, no memory is left allocated
* that would require freeing with lzma_end() even if some memory was
* associated with the lzma_stream structure when the initialization
* function was called.
*
* - Use lzma_code() to do the actual work.
*
* - Once the coding has been finished, the existing lzma_stream can be
* reused. It is OK to reuse lzma_stream with different initialization
* function without calling lzma_end() first. Old allocations are
* automatically freed.
*
* - Finally, use lzma_end() to free the allocated memory. lzma_end() never
* frees the lzma_stream structure itself.
*
* Application may modify the values of total_in and total_out as it wants.
* They are updated by liblzma to match the amount of data read and
* written, but aren't used for anything else.
*/
typedef struct {
const uint8_t *next_in; /**< Pointer to the next input byte. */
size_t avail_in; /**< Number of available input bytes in next_in. */
uint64_t total_in; /**< Total number of bytes read by liblzma. */
uint8_t *next_out; /**< Pointer to the next output position. */
size_t avail_out; /**< Amount of free space in next_out. */
uint64_t total_out; /**< Total number of bytes written by liblzma. */
/**
* \brief Custom memory allocation functions
*
* In most cases this is NULL which makes liblzma use
* the standard malloc() and free().
*/
lzma_allocator *allocator;
/** Internal state is not visible to applications. */
lzma_internal *internal;
/*
* Reserved space to allow possible future extensions without
* breaking the ABI. Excluding the initialization of this structure,
* you should not touch these, because the names of these variables
* may change.
*/
void *reserved_ptr1;
void *reserved_ptr2;
void *reserved_ptr3;
void *reserved_ptr4;
uint64_t reserved_int1;
uint64_t reserved_int2;
size_t reserved_int3;
size_t reserved_int4;
lzma_reserved_enum reserved_enum1;
lzma_reserved_enum reserved_enum2;
} lzma_stream;
/**
* \brief Initialization for lzma_stream
*
* When you declare an instance of lzma_stream, you can immediately
* initialize it so that initialization functions know that no memory
* has been allocated yet:
*
* lzma_stream strm = LZMA_STREAM_INIT;
*
* If you need to initialize a dynamically allocated lzma_stream, you can use
* memset(strm_pointer, 0, sizeof(lzma_stream)). Strictly speaking, this
* violates the C standard since NULL may have different internal
* representation than zero, but it should be portable enough in practice.
* Anyway, for maximum portability, you can use something like this:
*
* lzma_stream tmp = LZMA_STREAM_INIT;
* *strm = tmp;
*/
#define LZMA_STREAM_INIT \
{ NULL, 0, 0, NULL, 0, 0, NULL, NULL, \
NULL, NULL, NULL, NULL, 0, 0, 0, 0, \
LZMA_RESERVED_ENUM, LZMA_RESERVED_ENUM }
/**
* \brief Encode or decode data
*
* Once the lzma_stream has been successfully initialized (e.g. with
* lzma_stream_encoder()), the actual encoding or decoding is done
* using this function. The application has to update strm->next_in,
* strm->avail_in, strm->next_out, and strm->avail_out to pass input
* to and get output from liblzma.
*
* See the description of the coder-specific initialization function to find
* out what `action' values are supported by the coder.
*/
extern LZMA_API(lzma_ret) lzma_code(lzma_stream *strm, lzma_action action)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Free memory allocated for the coder data structures
*
* \param strm Pointer to lzma_stream that is at least initialized
* with LZMA_STREAM_INIT.
*
* After lzma_end(strm), strm->internal is guaranteed to be NULL. No other
* members of the lzma_stream structure are touched.
*
* \note zlib indicates an error if application end()s unfinished
* stream structure. liblzma doesn't do this, and assumes that
* application knows what it is doing.
*/
extern LZMA_API(void) lzma_end(lzma_stream *strm) lzma_nothrow;
/**
* \brief Get the memory usage of decoder filter chain
*
* This function is currently supported only when *strm has been initialized
* with a function that takes a memlimit argument. With other functions, you
* should use e.g. lzma_raw_encoder_memusage() or lzma_raw_decoder_memusage()
* to estimate the memory requirements.
*
* This function is useful e.g. after LZMA_MEMLIMIT_ERROR to find out how big
* the memory usage limit should have been to decode the input. Note that
* this may give misleading information if decoding .xz Streams that have
* multiple Blocks, because each Block can have different memory requirements.
*
* \return How much memory is currently allocated for the filter
* decoders. If no filter chain is currently allocated,
* some non-zero value is still returned, which is less than
* or equal to what any filter chain would indicate as its
* memory requirement.
*
* If this function isn't supported by *strm or some other error
* occurs, zero is returned.
*/
extern LZMA_API(uint64_t) lzma_memusage(const lzma_stream *strm)
lzma_nothrow lzma_attr_pure;
/**
* \brief Get the current memory usage limit
*
* This function is supported only when *strm has been initialized with
* a function that takes a memlimit argument.
*
* \return On success, the current memory usage limit is returned
* (always non-zero). On error, zero is returned.
*/
extern LZMA_API(uint64_t) lzma_memlimit_get(const lzma_stream *strm)
lzma_nothrow lzma_attr_pure;
/**
* \brief Set the memory usage limit
*
* This function is supported only when *strm has been initialized with
* a function that takes a memlimit argument.
*
* \return - LZMA_OK: New memory usage limit successfully set.
* - LZMA_MEMLIMIT_ERROR: The new limit is too small.
* The limit was not changed.
* - LZMA_PROG_ERROR: Invalid arguments, e.g. *strm doesn't
* support memory usage limit or memlimit was zero.
*/
extern LZMA_API(lzma_ret) lzma_memlimit_set(
lzma_stream *strm, uint64_t memlimit) lzma_nothrow;

View File

@@ -1,95 +0,0 @@
/**
* \file lzma/bcj.h
* \brief Branch/Call/Jump conversion filters
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/* Filter IDs for lzma_filter.id */
#define LZMA_FILTER_X86 LZMA_VLI_C(0x04)
/**<
* Filter for x86 binaries
*/
#define LZMA_FILTER_POWERPC LZMA_VLI_C(0x05)
/**<
* Filter for Big endian PowerPC binaries
*/
#define LZMA_FILTER_IA64 LZMA_VLI_C(0x06)
/**<
* Filter for IA-64 (Itanium) binaries.
*/
#define LZMA_FILTER_ARM LZMA_VLI_C(0x07)
/**<
* Filter for ARM binaries.
*/
#define LZMA_FILTER_ARMTHUMB LZMA_VLI_C(0x08)
/**<
* Filter for ARM-Thumb binaries.
*/
#define LZMA_FILTER_SPARC LZMA_VLI_C(0x09)
/**<
* Filter for SPARC binaries.
*/
/**
* \brief Options for BCJ filters
*
* The BCJ filters never change the size of the data. Specifying options
* for them is optional: if pointer to options is NULL, default value is
* used. You probably never need to specify options to BCJ filters, so just
* set the options pointer to NULL and be happy.
*
* If options with non-default values have been specified when encoding,
* the same options must also be specified when decoding.
*
* \note At the moment, none of the BCJ filters support
* LZMA_SYNC_FLUSH. If LZMA_SYNC_FLUSH is specified,
* LZMA_OPTIONS_ERROR will be returned. If there is need,
* partial support for LZMA_SYNC_FLUSH can be added in future.
* Partial means that flushing would be possible only at
* offsets that are multiple of 2, 4, or 16 depending on
* the filter, except x86 which cannot be made to support
* LZMA_SYNC_FLUSH predictably.
*/
typedef struct {
/**
* \brief Start offset for conversions
*
* This setting is useful only when the same filter is used
* _separately_ for multiple sections of the same executable file,
* and the sections contain cross-section branch/call/jump
* instructions. In that case it is beneficial to set the start
* offset of the non-first sections so that the relative addresses
* of the cross-section branch/call/jump instructions will use the
* same absolute addresses as in the first section.
*
* When the pointer to options is NULL, the default value (zero)
* is used.
*/
uint32_t start_offset;
} lzma_options_bcj;

View File

@@ -1,535 +0,0 @@
/**
* \file lzma/block.h
* \brief .xz Block handling
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Options for the Block and Block Header encoders and decoders
*
* Different Block handling functions use different parts of this structure.
* Some read some members, other functions write, and some do both. Only the
* members listed for reading need to be initialized when the specified
* functions are called. The members marked for writing will be assigned
* new values at some point either by calling the given function or by
* later calls to lzma_code().
*/
typedef struct {
/**
* \brief Block format version
*
* To prevent API and ABI breakages if new features are needed in
* the Block field, a version number is used to indicate which
* fields in this structure are in use. For now, version must always
* be zero. With non-zero version, most Block related functions will
* return LZMA_OPTIONS_ERROR.
*
* Read by:
* - All functions that take pointer to lzma_block as argument,
* including lzma_block_header_decode().
*
* Written by:
* - lzma_block_header_decode()
*/
uint32_t version;
/**
* \brief Size of the Block Header field
*
* This is always a multiple of four.
*
* Read by:
* - lzma_block_header_encode()
* - lzma_block_header_decode()
* - lzma_block_compressed_size()
* - lzma_block_unpadded_size()
* - lzma_block_total_size()
* - lzma_block_decoder()
* - lzma_block_buffer_decode()
*
* Written by:
* - lzma_block_header_size()
* - lzma_block_buffer_encode()
*/
uint32_t header_size;
# define LZMA_BLOCK_HEADER_SIZE_MIN 8
# define LZMA_BLOCK_HEADER_SIZE_MAX 1024
/**
* \brief Type of integrity Check
*
* The Check ID is not stored into the Block Header, thus its value
* must be provided also when decoding.
*
* Read by:
* - lzma_block_header_encode()
* - lzma_block_header_decode()
* - lzma_block_compressed_size()
* - lzma_block_unpadded_size()
* - lzma_block_total_size()
* - lzma_block_encoder()
* - lzma_block_decoder()
* - lzma_block_buffer_encode()
* - lzma_block_buffer_decode()
*/
lzma_check check;
/**
* \brief Size of the Compressed Data in bytes
*
* Encoding: If this is not LZMA_VLI_UNKNOWN, Block Header encoder
* will store this value to the Block Header. Block encoder doesn't
* care about this value, but will set it once the encoding has been
* finished.
*
* Decoding: If this is not LZMA_VLI_UNKNOWN, Block decoder will
* verify that the size of the Compressed Data field matches
* compressed_size.
*
* Usually you don't know this value when encoding in streamed mode,
* and thus cannot write this field into the Block Header.
*
* In non-streamed mode you can reserve space for this field before
* encoding the actual Block. After encoding the data, finish the
* Block by encoding the Block Header. Steps in detail:
*
* - Set compressed_size to some big enough value. If you don't know
* better, use LZMA_VLI_MAX, but remember that bigger values take
* more space in Block Header.
*
* - Call lzma_block_header_size() to see how much space you need to
* reserve for the Block Header.
*
* - Encode the Block using lzma_block_encoder() and lzma_code().
* It sets compressed_size to the correct value.
*
* - Use lzma_block_header_encode() to encode the Block Header.
* Because space was reserved in the first step, you don't need
* to call lzma_block_header_size() anymore, because due to
* reserving, header_size has to be big enough. If it is "too big",
* lzma_block_header_encode() will add enough Header Padding to
* make Block Header to match the size specified by header_size.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encode()
* - lzma_block_compressed_size()
* - lzma_block_unpadded_size()
* - lzma_block_total_size()
* - lzma_block_decoder()
* - lzma_block_buffer_decode()
*
* Written by:
* - lzma_block_header_decode()
* - lzma_block_compressed_size()
* - lzma_block_encoder()
* - lzma_block_decoder()
* - lzma_block_buffer_encode()
* - lzma_block_buffer_decode()
*/
lzma_vli compressed_size;
/**
* \brief Uncompressed Size in bytes
*
* This is handled very similarly to compressed_size above.
*
* uncompressed_size is needed by fewer functions than
* compressed_size. This is because uncompressed_size isn't
* needed to validate that Block stays within proper limits.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encode()
* - lzma_block_decoder()
* - lzma_block_buffer_decode()
*
* Written by:
* - lzma_block_header_decode()
* - lzma_block_encoder()
* - lzma_block_decoder()
* - lzma_block_buffer_encode()
* - lzma_block_buffer_decode()
*/
lzma_vli uncompressed_size;
/**
* \brief Array of filters
*
* There can be 1-4 filters. The end of the array is marked with
* .id = LZMA_VLI_UNKNOWN.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encode()
* - lzma_block_encoder()
* - lzma_block_decoder()
* - lzma_block_buffer_encode()
* - lzma_block_buffer_decode()
*
* Written by:
* - lzma_block_header_decode(): Note that this does NOT free()
* the old filter options structures. All unused filters[] will
* have .id == LZMA_VLI_UNKNOWN and .options == NULL. If
* decoding fails, all filters[] are guaranteed to be
* LZMA_VLI_UNKNOWN and NULL.
*
* \note Because of the array is terminated with
* .id = LZMA_VLI_UNKNOWN, the actual array must
* have LZMA_FILTERS_MAX + 1 members or the Block
* Header decoder will overflow the buffer.
*/
lzma_filter *filters;
/**
* \brief Raw value stored in the Check field
*
* After successful coding, the first lzma_check_size(check) bytes
* of this array contain the raw value stored in the Check field.
*
* Note that CRC32 and CRC64 are stored in little endian byte order.
* Take it into account if you display the Check values to the user.
*
* Written by:
* - lzma_block_encoder()
* - lzma_block_decoder()
* - lzma_block_buffer_encode()
* - lzma_block_buffer_decode()
*/
uint8_t raw_check[LZMA_CHECK_SIZE_MAX];
/*
* Reserved space to allow possible future extensions without
* breaking the ABI. You should not touch these, because the names
* of these variables may change. These are and will never be used
* with the currently supported options, so it is safe to leave these
* uninitialized.
*/
void *reserved_ptr1;
void *reserved_ptr2;
void *reserved_ptr3;
uint32_t reserved_int1;
uint32_t reserved_int2;
lzma_vli reserved_int3;
lzma_vli reserved_int4;
lzma_vli reserved_int5;
lzma_vli reserved_int6;
lzma_vli reserved_int7;
lzma_vli reserved_int8;
lzma_reserved_enum reserved_enum1;
lzma_reserved_enum reserved_enum2;
lzma_reserved_enum reserved_enum3;
lzma_reserved_enum reserved_enum4;
lzma_bool reserved_bool1;
lzma_bool reserved_bool2;
lzma_bool reserved_bool3;
lzma_bool reserved_bool4;
lzma_bool reserved_bool5;
lzma_bool reserved_bool6;
lzma_bool reserved_bool7;
lzma_bool reserved_bool8;
} lzma_block;
/**
* \brief Decode the Block Header Size field
*
* To decode Block Header using lzma_block_header_decode(), the size of the
* Block Header has to be known and stored into lzma_block.header_size.
* The size can be calculated from the first byte of a Block using this macro.
* Note that if the first byte is 0x00, it indicates beginning of Index; use
* this macro only when the byte is not 0x00.
*
* There is no encoding macro, because Block Header encoder is enough for that.
*/
#define lzma_block_header_size_decode(b) (((uint32_t)(b) + 1) * 4)
/**
* \brief Calculate Block Header Size
*
* Calculate the minimum size needed for the Block Header field using the
* settings specified in the lzma_block structure. Note that it is OK to
* increase the calculated header_size value as long as it is a multiple of
* four and doesn't exceed LZMA_BLOCK_HEADER_SIZE_MAX. Increasing header_size
* just means that lzma_block_header_encode() will add Header Padding.
*
* \return - LZMA_OK: Size calculated successfully and stored to
* block->header_size.
* - LZMA_OPTIONS_ERROR: Unsupported version, filters or
* filter options.
* - LZMA_PROG_ERROR: Invalid values like compressed_size == 0.
*
* \note This doesn't check that all the options are valid i.e. this
* may return LZMA_OK even if lzma_block_header_encode() or
* lzma_block_encoder() would fail. If you want to validate the
* filter chain, consider using lzma_memlimit_encoder() which as
* a side-effect validates the filter chain.
*/
extern LZMA_API(lzma_ret) lzma_block_header_size(lzma_block *block)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Encode Block Header
*
* The caller must have calculated the size of the Block Header already with
* lzma_block_header_size(). If a value larger than the one calculated by
* lzma_block_header_size() is used, the Block Header will be padded to the
* specified size.
*
* \param out Beginning of the output buffer. This must be
* at least block->header_size bytes.
* \param block Block options to be encoded.
*
* \return - LZMA_OK: Encoding was successful. block->header_size
* bytes were written to output buffer.
* - LZMA_OPTIONS_ERROR: Invalid or unsupported options.
* - LZMA_PROG_ERROR: Invalid arguments, for example
* block->header_size is invalid or block->filters is NULL.
*/
extern LZMA_API(lzma_ret) lzma_block_header_encode(
const lzma_block *block, uint8_t *out)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Decode Block Header
*
* block->version should be set to the highest value supported by the
* application; currently the only possible version is zero. This function
* will set version to the lowest value that still supports all the features
* required by the Block Header.
*
* The size of the Block Header must have already been decoded with
* lzma_block_header_size_decode() macro and stored to block->header_size.
*
* block->filters must have been allocated, but they don't need to be
* initialized (possible existing filter options are not freed).
*
* \param block Destination for Block options.
* \param allocator lzma_allocator for custom allocator functions.
* Set to NULL to use malloc() (and also free()
* if an error occurs).
* \param in Beginning of the input buffer. This must be
* at least block->header_size bytes.
*
* \return - LZMA_OK: Decoding was successful. block->header_size
* bytes were read from the input buffer.
* - LZMA_OPTIONS_ERROR: The Block Header specifies some
* unsupported options such as unsupported filters. This can
* happen also if block->version was set to a too low value
* compared to what would be required to properly represent
* the information stored in the Block Header.
* - LZMA_DATA_ERROR: Block Header is corrupt, for example,
* the CRC32 doesn't match.
* - LZMA_PROG_ERROR: Invalid arguments, for example
* block->header_size is invalid or block->filters is NULL.
*/
extern LZMA_API(lzma_ret) lzma_block_header_decode(lzma_block *block,
lzma_allocator *allocator, const uint8_t *in)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Validate and set Compressed Size according to Unpadded Size
*
* Block Header stores Compressed Size, but Index has Unpadded Size. If the
* application has already parsed the Index and is now decoding Blocks,
* it can calculate Compressed Size from Unpadded Size. This function does
* exactly that with error checking:
*
* - Compressed Size calculated from Unpadded Size must be positive integer,
* that is, Unpadded Size must be big enough that after Block Header and
* Check fields there's still at least one byte for Compressed Size.
*
* - If Compressed Size was present in Block Header, the new value
* calculated from Unpadded Size is compared against the value
* from Block Header.
*
* \note This function must be called _after_ decoding the Block Header
* field so that it can properly validate Compressed Size if it
* was present in Block Header.
*
* \return - LZMA_OK: block->compressed_size was set successfully.
* - LZMA_DATA_ERROR: unpadded_size is too small compared to
* block->header_size and lzma_check_size(block->check).
* - LZMA_PROG_ERROR: Some values are invalid. For example,
* block->header_size must be a multiple of four and
* between 8 and 1024 inclusive.
*/
extern LZMA_API(lzma_ret) lzma_block_compressed_size(
lzma_block *block, lzma_vli unpadded_size)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Calculate Unpadded Size
*
* The Index field stores Unpadded Size and Uncompressed Size. The latter
* can be taken directly from the lzma_block structure after coding a Block,
* but Unpadded Size needs to be calculated from Block Header Size,
* Compressed Size, and size of the Check field. This is where this function
* is needed.
*
* \return Unpadded Size on success, or zero on error.
*/
extern LZMA_API(lzma_vli) lzma_block_unpadded_size(const lzma_block *block)
lzma_nothrow lzma_attr_pure;
/**
* \brief Calculate the total encoded size of a Block
*
* This is equivalent to lzma_block_unpadded_size() except that the returned
* value includes the size of the Block Padding field.
*
* \return On success, total encoded size of the Block. On error,
* zero is returned.
*/
extern LZMA_API(lzma_vli) lzma_block_total_size(const lzma_block *block)
lzma_nothrow lzma_attr_pure;
/**
* \brief Initialize .xz Block encoder
*
* Valid actions for lzma_code() are LZMA_RUN, LZMA_SYNC_FLUSH (only if the
* filter chain supports it), and LZMA_FINISH.
*
* \return - LZMA_OK: All good, continue with lzma_code().
* - LZMA_MEM_ERROR
* - LZMA_OPTIONS_ERROR
* - LZMA_UNSUPPORTED_CHECK: block->check specifies a Check ID
* that is not supported by this buid of liblzma. Initializing
* the encoder failed.
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_block_encoder(
lzma_stream *strm, lzma_block *block)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Initialize .xz Block decoder
*
* Valid actions for lzma_code() are LZMA_RUN and LZMA_FINISH. Using
* LZMA_FINISH is not required. It is supported only for convenience.
*
* \return - LZMA_OK: All good, continue with lzma_code().
* - LZMA_UNSUPPORTED_CHECK: Initialization was successful, but
* the given Check ID is not supported, thus Check will be
* ignored.
* - LZMA_PROG_ERROR
* - LZMA_MEM_ERROR
*/
extern LZMA_API(lzma_ret) lzma_block_decoder(
lzma_stream *strm, lzma_block *block)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Calculate maximum output size for single-call Block encoding
*
* This is equivalent to lzma_stream_buffer_bound() but for .xz Blocks.
* See the documentation of lzma_stream_buffer_bound().
*/
extern LZMA_API(size_t) lzma_block_buffer_bound(size_t uncompressed_size)
lzma_nothrow;
/**
* \brief Single-call .xz Block encoder
*
* In contrast to the multi-call encoder initialized with
* lzma_block_encoder(), this function encodes also the Block Header. This
* is required to make it possible to write appropriate Block Header also
* in case the data isn't compressible, and different filter chain has to be
* used to encode the data in uncompressed form using uncompressed chunks
* of the LZMA2 filter.
*
* When the data isn't compressible, header_size, compressed_size, and
* uncompressed_size are set just like when the data was compressible, but
* it is possible that header_size is too small to hold the filter chain
* specified in block->filters, because that isn't necessarily the filter
* chain that was actually used to encode the data. lzma_block_unpadded_size()
* still works normally, because it doesn't read the filters array.
*
* \param block Block options: block->version, block->check,
* and block->filters must have been initialized.
* \param allocator lzma_allocator for custom allocator functions.
* Set to NULL to use malloc() and free().
* \param in Beginning of the input buffer
* \param in_size Size of the input buffer
* \param out Beginning of the output buffer
* \param out_pos The next byte will be written to out[*out_pos].
* *out_pos is updated only if encoding succeeds.
* \param out_size Size of the out buffer; the first byte into
* which no data is written to is out[out_size].
*
* \return - LZMA_OK: Encoding was successful.
* - LZMA_BUF_ERROR: Not enough output buffer space.
* - LZMA_UNSUPPORTED_CHECK
* - LZMA_OPTIONS_ERROR
* - LZMA_MEM_ERROR
* - LZMA_DATA_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_block_buffer_encode(
lzma_block *block, lzma_allocator *allocator,
const uint8_t *in, size_t in_size,
uint8_t *out, size_t *out_pos, size_t out_size)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Single-call .xz Block decoder
*
* This is single-call equivalent of lzma_block_decoder(), and requires that
* the caller has already decoded Block Header and checked its memory usage.
*
* \param block Block options just like with lzma_block_decoder().
* \param allocator lzma_allocator for custom allocator functions.
* Set to NULL to use malloc() and free().
* \param in Beginning of the input buffer
* \param in_pos The next byte will be read from in[*in_pos].
* *in_pos is updated only if decoding succeeds.
* \param in_size Size of the input buffer; the first byte that
* won't be read is in[in_size].
* \param out Beginning of the output buffer
* \param out_pos The next byte will be written to out[*out_pos].
* *out_pos is updated only if encoding succeeds.
* \param out_size Size of the out buffer; the first byte into
* which no data is written to is out[out_size].
*
* \return - LZMA_OK: Decoding was successful.
* - LZMA_OPTIONS_ERROR
* - LZMA_DATA_ERROR
* - LZMA_MEM_ERROR
* - LZMA_BUF_ERROR: Output buffer was too small.
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_block_buffer_decode(
lzma_block *block, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos, size_t in_size,
uint8_t *out, size_t *out_pos, size_t out_size)
lzma_nothrow;

View File

@@ -1,155 +0,0 @@
/**
* \file lzma/check.h
* \brief Integrity checks
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Type of the integrity check (Check ID)
*
* The .xz format supports multiple types of checks that are calculated
* from the uncompressed data. They vary in both speed and ability to
* detect errors.
*/
typedef enum {
LZMA_CHECK_NONE = 0,
/**<
* No Check is calculated.
*
* Size of the Check field: 0 bytes
*/
LZMA_CHECK_CRC32 = 1,
/**<
* CRC32 using the polynomial from the IEEE 802.3 standard
*
* Size of the Check field: 4 bytes
*/
LZMA_CHECK_CRC64 = 4,
/**<
* CRC64 using the polynomial from the ECMA-182 standard
*
* Size of the Check field: 8 bytes
*/
LZMA_CHECK_SHA256 = 10
/**<
* SHA-256
*
* Size of the Check field: 32 bytes
*/
} lzma_check;
/**
* \brief Maximum valid Check ID
*
* The .xz file format specification specifies 16 Check IDs (0-15). Some
* of them are only reserved, that is, no actual Check algorithm has been
* assigned. When decoding, liblzma still accepts unknown Check IDs for
* future compatibility. If a valid but unsupported Check ID is detected,
* liblzma can indicate a warning; see the flags LZMA_TELL_NO_CHECK,
* LZMA_TELL_UNSUPPORTED_CHECK, and LZMA_TELL_ANY_CHECK in container.h.
*/
#define LZMA_CHECK_ID_MAX 15
/**
* \brief Test if the given Check ID is supported
*
* Return true if the given Check ID is supported by this liblzma build.
* Otherwise false is returned. It is safe to call this with a value that
* is not in the range [0, 15]; in that case the return value is always false.
*
* You can assume that LZMA_CHECK_NONE and LZMA_CHECK_CRC32 are always
* supported (even if liblzma is built with limited features).
*/
extern LZMA_API(lzma_bool) lzma_check_is_supported(lzma_check check)
lzma_nothrow lzma_attr_const;
/**
* \brief Get the size of the Check field with the given Check ID
*
* Although not all Check IDs have a check algorithm associated, the size of
* every Check is already frozen. This function returns the size (in bytes) of
* the Check field with the specified Check ID. The values are:
* { 0, 4, 4, 4, 8, 8, 8, 16, 16, 16, 32, 32, 32, 64, 64, 64 }
*
* If the argument is not in the range [0, 15], UINT32_MAX is returned.
*/
extern LZMA_API(uint32_t) lzma_check_size(lzma_check check)
lzma_nothrow lzma_attr_const;
/**
* \brief Maximum size of a Check field
*/
#define LZMA_CHECK_SIZE_MAX 64
/**
* \brief Calculate CRC32
*
* Calculate CRC32 using the polynomial from the IEEE 802.3 standard.
*
* \param buf Pointer to the input buffer
* \param size Size of the input buffer
* \param crc Previously returned CRC value. This is used to
* calculate the CRC of a big buffer in smaller chunks.
* Set to zero when starting a new calculation.
*
* \return Updated CRC value, which can be passed to this function
* again to continue CRC calculation.
*/
extern LZMA_API(uint32_t) lzma_crc32(
const uint8_t *buf, size_t size, uint32_t crc)
lzma_nothrow lzma_attr_pure;
/**
* \brief Calculate CRC64
*
* Calculate CRC64 using the polynomial from the ECMA-182 standard.
*
* This function is used similarly to lzma_crc32(). See its documentation.
*/
extern LZMA_API(uint64_t) lzma_crc64(
const uint8_t *buf, size_t size, uint64_t crc)
lzma_nothrow lzma_attr_pure;
/*
* SHA-256 functions are currently not exported to public API.
* Contact Lasse Collin if you think it should be.
*/
/**
* \brief Get the type of the integrity check
*
* This function can be called only immediately after lzma_code() has
* returned LZMA_NO_CHECK, LZMA_UNSUPPORTED_CHECK, or LZMA_GET_CHECK.
* Calling this function in any other situation has undefined behavior.
*/
extern LZMA_API(lzma_check) lzma_get_check(const lzma_stream *strm)
lzma_nothrow;

View File

@@ -1,429 +0,0 @@
/**
* \file lzma/container.h
* \brief File formats
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/************
* Encoding *
************/
/**
* \brief Default compression preset
*
* It's not straightforward to recommend a default preset, because in some
* cases keeping the resource usage relatively low is more important that
* getting the maximum compression ratio.
*/
#define LZMA_PRESET_DEFAULT UINT32_C(6)
/**
* \brief Mask for preset level
*
* This is useful only if you need to extract the level from the preset
* variable. That should be rare.
*/
#define LZMA_PRESET_LEVEL_MASK UINT32_C(0x1F)
/*
* Preset flags
*
* Currently only one flag is defined.
*/
/**
* \brief Extreme compression preset
*
* This flag modifies the preset to make the encoding significantly slower
* while improving the compression ratio only marginally. This is useful
* when you don't mind wasting time to get as small result as possible.
*
* This flag doesn't affect the memory usage requirements of the decoder (at
* least not significantly). The memory usage of the encoder may be increased
* a little but only at the lowest preset levels (0-3).
*/
#define LZMA_PRESET_EXTREME (UINT32_C(1) << 31)
/**
* \brief Calculate approximate memory usage of easy encoder
*
* This function is a wrapper for lzma_raw_encoder_memusage().
*
* \param preset Compression preset (level and possible flags)
*
* \return Number of bytes of memory required for the given
* preset when encoding. If an error occurs, for example
* due to unsupported preset, UINT64_MAX is returned.
*/
extern LZMA_API(uint64_t) lzma_easy_encoder_memusage(uint32_t preset)
lzma_nothrow lzma_attr_pure;
/**
* \brief Calculate approximate decoder memory usage of a preset
*
* This function is a wrapper for lzma_raw_decoder_memusage().
*
* \param preset Compression preset (level and possible flags)
*
* \return Number of bytes of memory required to decompress a file
* that was compressed using the given preset. If an error
* occurs, for example due to unsupported preset, UINT64_MAX
* is returned.
*/
extern LZMA_API(uint64_t) lzma_easy_decoder_memusage(uint32_t preset)
lzma_nothrow lzma_attr_pure;
/**
* \brief Initialize .xz Stream encoder using a preset number
*
* This function is intended for those who just want to use the basic features
* if liblzma (that is, most developers out there).
*
* \param strm Pointer to lzma_stream that is at least initialized
* with LZMA_STREAM_INIT.
* \param preset Compression preset to use. A preset consist of level
* number and zero or more flags. Usually flags aren't
* used, so preset is simply a number [0, 9] which match
* the options -0 ... -9 of the xz command line tool.
* Additional flags can be be set using bitwise-or with
* the preset level number, e.g. 6 | LZMA_PRESET_EXTREME.
* \param check Integrity check type to use. See check.h for available
* checks. The xz command line tool defaults to
* LZMA_CHECK_CRC64, which is a good choice if you are
* unsure. LZMA_CHECK_CRC32 is good too as long as the
* uncompressed file is not many gigabytes.
*
* \return - LZMA_OK: Initialization succeeded. Use lzma_code() to
* encode your data.
* - LZMA_MEM_ERROR: Memory allocation failed.
* - LZMA_OPTIONS_ERROR: The given compression preset is not
* supported by this build of liblzma.
* - LZMA_UNSUPPORTED_CHECK: The given check type is not
* supported by this liblzma build.
* - LZMA_PROG_ERROR: One or more of the parameters have values
* that will never be valid. For example, strm == NULL.
*
* If initialization fails (return value is not LZMA_OK), all the memory
* allocated for *strm by liblzma is always freed. Thus, there is no need
* to call lzma_end() after failed initialization.
*
* If initialization succeeds, use lzma_code() to do the actual encoding.
* Valid values for `action' (the second argument of lzma_code()) are
* LZMA_RUN, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, and LZMA_FINISH. In future,
* there may be compression levels or flags that don't support LZMA_SYNC_FLUSH.
*/
extern LZMA_API(lzma_ret) lzma_easy_encoder(
lzma_stream *strm, uint32_t preset, lzma_check check)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Single-call .xz Stream encoding using a preset number
*
* The maximum required output buffer size can be calculated with
* lzma_stream_buffer_bound().
*
* \param preset Compression preset to use. See the description
* in lzma_easy_encoder().
* \param check Type of the integrity check to calculate from
* uncompressed data.
* \param allocator lzma_allocator for custom allocator functions.
* Set to NULL to use malloc() and free().
* \param in Beginning of the input buffer
* \param in_size Size of the input buffer
* \param out Beginning of the output buffer
* \param out_pos The next byte will be written to out[*out_pos].
* *out_pos is updated only if encoding succeeds.
* \param out_size Size of the out buffer; the first byte into
* which no data is written to is out[out_size].
*
* \return - LZMA_OK: Encoding was successful.
* - LZMA_BUF_ERROR: Not enough output buffer space.
* - LZMA_UNSUPPORTED_CHECK
* - LZMA_OPTIONS_ERROR
* - LZMA_MEM_ERROR
* - LZMA_DATA_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_easy_buffer_encode(
uint32_t preset, lzma_check check,
lzma_allocator *allocator, const uint8_t *in, size_t in_size,
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
/**
* \brief Initialize .xz Stream encoder using a custom filter chain
*
* \param strm Pointer to properly prepared lzma_stream
* \param filters Array of filters. This must be terminated with
* filters[n].id = LZMA_VLI_UNKNOWN. See filter.h for
* more information.
* \param check Type of the integrity check to calculate from
* uncompressed data.
*
* \return - LZMA_OK: Initialization was successful.
* - LZMA_MEM_ERROR
* - LZMA_UNSUPPORTED_CHECK
* - LZMA_OPTIONS_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_stream_encoder(lzma_stream *strm,
const lzma_filter *filters, lzma_check check)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Initialize .lzma encoder (legacy file format)
*
* The .lzma format is sometimes called the LZMA_Alone format, which is the
* reason for the name of this function. The .lzma format supports only the
* LZMA1 filter. There is no support for integrity checks like CRC32.
*
* Use this function if and only if you need to create files readable by
* legacy LZMA tools such as LZMA Utils 4.32.x. Moving to the .xz format
* is strongly recommended.
*
* The valid action values for lzma_code() are LZMA_RUN and LZMA_FINISH.
* No kind of flushing is supported, because the file format doesn't make
* it possible.
*
* \return - LZMA_OK
* - LZMA_MEM_ERROR
* - LZMA_OPTIONS_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_alone_encoder(
lzma_stream *strm, const lzma_options_lzma *options)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Calculate output buffer size for single-call Stream encoder
*
* When trying to compress uncompressible data, the encoded size will be
* slightly bigger than the input data. This function calculates how much
* output buffer space is required to be sure that lzma_stream_buffer_encode()
* doesn't return LZMA_BUF_ERROR.
*
* The calculated value is not exact, but it is guaranteed to be big enough.
* The actual maximum output space required may be slightly smaller (up to
* about 100 bytes). This should not be a problem in practice.
*
* If the calculated maximum size doesn't fit into size_t or would make the
* Stream grow past LZMA_VLI_MAX (which should never happen in practice),
* zero is returned to indicate the error.
*
* \note The limit calculated by this function applies only to
* single-call encoding. Multi-call encoding may (and probably
* will) have larger maximum expansion when encoding
* uncompressible data. Currently there is no function to
* calculate the maximum expansion of multi-call encoding.
*/
extern LZMA_API(size_t) lzma_stream_buffer_bound(size_t uncompressed_size)
lzma_nothrow;
/**
* \brief Single-call .xz Stream encoder
*
* \param filters Array of filters. This must be terminated with
* filters[n].id = LZMA_VLI_UNKNOWN. See filter.h
* for more information.
* \param check Type of the integrity check to calculate from
* uncompressed data.
* \param allocator lzma_allocator for custom allocator functions.
* Set to NULL to use malloc() and free().
* \param in Beginning of the input buffer
* \param in_size Size of the input buffer
* \param out Beginning of the output buffer
* \param out_pos The next byte will be written to out[*out_pos].
* *out_pos is updated only if encoding succeeds.
* \param out_size Size of the out buffer; the first byte into
* which no data is written to is out[out_size].
*
* \return - LZMA_OK: Encoding was successful.
* - LZMA_BUF_ERROR: Not enough output buffer space.
* - LZMA_UNSUPPORTED_CHECK
* - LZMA_OPTIONS_ERROR
* - LZMA_MEM_ERROR
* - LZMA_DATA_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_stream_buffer_encode(
lzma_filter *filters, lzma_check check,
lzma_allocator *allocator, const uint8_t *in, size_t in_size,
uint8_t *out, size_t *out_pos, size_t out_size)
lzma_nothrow lzma_attr_warn_unused_result;
/************
* Decoding *
************/
/**
* This flag makes lzma_code() return LZMA_NO_CHECK if the input stream
* being decoded has no integrity check. Note that when used with
* lzma_auto_decoder(), all .lzma files will trigger LZMA_NO_CHECK
* if LZMA_TELL_NO_CHECK is used.
*/
#define LZMA_TELL_NO_CHECK UINT32_C(0x01)
/**
* This flag makes lzma_code() return LZMA_UNSUPPORTED_CHECK if the input
* stream has an integrity check, but the type of the integrity check is not
* supported by this liblzma version or build. Such files can still be
* decoded, but the integrity check cannot be verified.
*/
#define LZMA_TELL_UNSUPPORTED_CHECK UINT32_C(0x02)
/**
* This flag makes lzma_code() return LZMA_GET_CHECK as soon as the type
* of the integrity check is known. The type can then be got with
* lzma_get_check().
*/
#define LZMA_TELL_ANY_CHECK UINT32_C(0x04)
/**
* This flag enables decoding of concatenated files with file formats that
* allow concatenating compressed files as is. From the formats currently
* supported by liblzma, only the .xz format allows concatenated files.
* Concatenated files are not allowed with the legacy .lzma format.
*
* This flag also affects the usage of the `action' argument for lzma_code().
* When LZMA_CONCATENATED is used, lzma_code() won't return LZMA_STREAM_END
* unless LZMA_FINISH is used as `action'. Thus, the application has to set
* LZMA_FINISH in the same way as it does when encoding.
*
* If LZMA_CONCATENATED is not used, the decoders still accept LZMA_FINISH
* as `action' for lzma_code(), but the usage of LZMA_FINISH isn't required.
*/
#define LZMA_CONCATENATED UINT32_C(0x08)
/**
* \brief Initialize .xz Stream decoder
*
* \param strm Pointer to properly prepared lzma_stream
* \param memlimit Memory usage limit as bytes. Use UINT64_MAX
* to effectively disable the limiter.
* \param flags Bitwise-or of zero or more of the decoder flags:
* LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK,
* LZMA_TELL_ANY_CHECK, LZMA_CONCATENATED
*
* \return - LZMA_OK: Initialization was successful.
* - LZMA_MEM_ERROR: Cannot allocate memory.
* - LZMA_OPTIONS_ERROR: Unsupported flags
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_stream_decoder(
lzma_stream *strm, uint64_t memlimit, uint32_t flags)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Decode .xz Streams and .lzma files with autodetection
*
* This decoder autodetects between the .xz and .lzma file formats, and
* calls lzma_stream_decoder() or lzma_alone_decoder() once the type
* of the input file has been detected.
*
* \param strm Pointer to properly prepared lzma_stream
* \param memlimit Memory usage limit as bytes. Use UINT64_MAX
* to effectively disable the limiter.
* \param flags Bitwise-or of flags, or zero for no flags.
*
* \return - LZMA_OK: Initialization was successful.
* - LZMA_MEM_ERROR: Cannot allocate memory.
* - LZMA_OPTIONS_ERROR: Unsupported flags
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_auto_decoder(
lzma_stream *strm, uint64_t memlimit, uint32_t flags)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Initialize .lzma decoder (legacy file format)
*
* Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.
* There is no need to use LZMA_FINISH, but allowing it may simplify
* certain types of applications.
*
* \return - LZMA_OK
* - LZMA_MEM_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_alone_decoder(
lzma_stream *strm, uint64_t memlimit)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Single-call .xz Stream decoder
*
* \param memlimit Pointer to how much memory the decoder is allowed
* to allocate. The value pointed by this pointer is
* modified if and only if LZMA_MEMLIMIT_ERROR is
* returned.
* \param flags Bitwise-or of zero or more of the decoder flags:
* LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK,
* LZMA_CONCATENATED. Note that LZMA_TELL_ANY_CHECK
* is not allowed and will return LZMA_PROG_ERROR.
* \param allocator lzma_allocator for custom allocator functions.
* Set to NULL to use malloc() and free().
* \param in Beginning of the input buffer
* \param in_pos The next byte will be read from in[*in_pos].
* *in_pos is updated only if decoding succeeds.
* \param in_size Size of the input buffer; the first byte that
* won't be read is in[in_size].
* \param out Beginning of the output buffer
* \param out_pos The next byte will be written to out[*out_pos].
* *out_pos is updated only if decoding succeeds.
* \param out_size Size of the out buffer; the first byte into
* which no data is written to is out[out_size].
*
* \return - LZMA_OK: Decoding was successful.
* - LZMA_FORMAT_ERROR
* - LZMA_OPTIONS_ERROR
* - LZMA_DATA_ERROR
* - LZMA_NO_CHECK: This can be returned only if using
* the LZMA_TELL_NO_CHECK flag.
* - LZMA_UNSUPPORTED_CHECK: This can be returned only if using
* the LZMA_TELL_UNSUPPORTED_CHECK flag.
* - LZMA_MEM_ERROR
* - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.
* The minimum required memlimit value was stored to *memlimit.
* - LZMA_BUF_ERROR: Output buffer was too small.
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_stream_buffer_decode(
uint64_t *memlimit, uint32_t flags, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos, size_t in_size,
uint8_t *out, size_t *out_pos, size_t out_size)
lzma_nothrow lzma_attr_warn_unused_result;

View File

@@ -1,82 +0,0 @@
/**
* \file lzma/delta.h
* \brief Delta filter
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Filter ID
*
* Filter ID of the Delta filter. This is used as lzma_filter.id.
*/
#define LZMA_FILTER_DELTA LZMA_VLI_C(0x03)
/**
* \brief Type of the delta calculation
*
* Currently only byte-wise delta is supported. Other possible types could
* be, for example, delta of 16/32/64-bit little/big endian integers, but
* these are not currently planned since byte-wise delta is almost as good.
*/
typedef enum {
LZMA_DELTA_TYPE_BYTE
} lzma_delta_type;
/**
* \brief Options for the Delta filter
*
* These options are needed by both encoder and decoder.
*/
typedef struct {
/** For now, this must always be LZMA_DELTA_TYPE_BYTE. */
lzma_delta_type type;
/**
* \brief Delta distance
*
* With the only currently supported type, LZMA_DELTA_TYPE_BYTE,
* the distance is as bytes.
*
* Examples:
* - 16-bit stereo audio: distance = 4 bytes
* - 24-bit RGB image data: distance = 3 bytes
*/
uint32_t dist;
# define LZMA_DELTA_DIST_MIN 1
# define LZMA_DELTA_DIST_MAX 256
/*
* Reserved space to allow possible future extensions without
* breaking the ABI. You should not touch these, because the names
* of these variables may change. These are and will never be used
* when type is LZMA_DELTA_TYPE_BYTE, so it is safe to leave these
* uninitialized.
*/
uint32_t reserved_int1;
uint32_t reserved_int2;
uint32_t reserved_int3;
uint32_t reserved_int4;
void *reserved_ptr1;
void *reserved_ptr2;
} lzma_options_delta;

View File

@@ -1,429 +0,0 @@
/**
* \file lzma/filter.h
* \brief Common filter related types and functions
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Maximum number of filters in a chain
*
* A filter chain can have 1-4 filters, of which three are allowed to change
* the size of the data. Usually only one or two filters are needed.
*/
#define LZMA_FILTERS_MAX 4
/**
* \brief Filter options
*
* This structure is used to pass Filter ID and a pointer filter's
* options to liblzma. A few functions work with a single lzma_filter
* structure, while most functions expect a filter chain.
*
* A filter chain is indicated with an array of lzma_filter structures.
* The array is terminated with .id = LZMA_VLI_UNKNOWN. Thus, the filter
* array must have LZMA_FILTERS_MAX + 1 elements (that is, five) to
* be able to hold any arbitrary filter chain. This is important when
* using lzma_block_header_decode() from block.h, because too small
* array would make liblzma write past the end of the filters array.
*/
typedef struct {
/**
* \brief Filter ID
*
* Use constants whose name begin with `LZMA_FILTER_' to specify
* different filters. In an array of lzma_filter structures, use
* LZMA_VLI_UNKNOWN to indicate end of filters.
*
* \note This is not an enum, because on some systems enums
* cannot be 64-bit.
*/
lzma_vli id;
/**
* \brief Pointer to filter-specific options structure
*
* If the filter doesn't need options, set this to NULL. If id is
* set to LZMA_VLI_UNKNOWN, options is ignored, and thus
* doesn't need be initialized.
*/
void *options;
} lzma_filter;
/**
* \brief Test if the given Filter ID is supported for encoding
*
* Return true if the give Filter ID is supported for encoding by this
* liblzma build. Otherwise false is returned.
*
* There is no way to list which filters are available in this particular
* liblzma version and build. It would be useless, because the application
* couldn't know what kind of options the filter would need.
*/
extern LZMA_API(lzma_bool) lzma_filter_encoder_is_supported(lzma_vli id)
lzma_nothrow lzma_attr_const;
/**
* \brief Test if the given Filter ID is supported for decoding
*
* Return true if the give Filter ID is supported for decoding by this
* liblzma build. Otherwise false is returned.
*/
extern LZMA_API(lzma_bool) lzma_filter_decoder_is_supported(lzma_vli id)
lzma_nothrow lzma_attr_const;
/**
* \brief Copy the filters array
*
* Copy the Filter IDs and filter-specific options from src to dest.
* Up to LZMA_FILTERS_MAX filters are copied, plus the terminating
* .id == LZMA_VLI_UNKNOWN. Thus, dest should have at least
* LZMA_FILTERS_MAX + 1 elements space unless the caller knows that
* src is smaller than that.
*
* Unless the filter-specific options is NULL, the Filter ID has to be
* supported by liblzma, because liblzma needs to know the size of every
* filter-specific options structure. The filter-specific options are not
* validated. If options is NULL, any unsupported Filter IDs are copied
* without returning an error.
*
* Old filter-specific options in dest are not freed, so dest doesn't
* need to be initialized by the caller in any way.
*
* If an error occurs, memory possibly already allocated by this function
* is always freed.
*
* \return - LZMA_OK
* - LZMA_MEM_ERROR
* - LZMA_OPTIONS_ERROR: Unsupported Filter ID and its options
* is not NULL.
* - LZMA_PROG_ERROR: src or dest is NULL.
*/
extern LZMA_API(lzma_ret) lzma_filters_copy(const lzma_filter *src,
lzma_filter *dest, lzma_allocator *allocator) lzma_nothrow;
/**
* \brief Calculate approximate memory requirements for raw encoder
*
* This function can be used to calculate the memory requirements for
* Block and Stream encoders too because Block and Stream encoders don't
* need significantly more memory than raw encoder.
*
* \param filters Array of filters terminated with
* .id == LZMA_VLI_UNKNOWN.
*
* \return Number of bytes of memory required for the given
* filter chain when encoding. If an error occurs,
* for example due to unsupported filter chain,
* UINT64_MAX is returned.
*/
extern LZMA_API(uint64_t) lzma_raw_encoder_memusage(const lzma_filter *filters)
lzma_nothrow lzma_attr_pure;
/**
* \brief Calculate approximate memory requirements for raw decoder
*
* This function can be used to calculate the memory requirements for
* Block and Stream decoders too because Block and Stream decoders don't
* need significantly more memory than raw decoder.
*
* \param filters Array of filters terminated with
* .id == LZMA_VLI_UNKNOWN.
*
* \return Number of bytes of memory required for the given
* filter chain when decoding. If an error occurs,
* for example due to unsupported filter chain,
* UINT64_MAX is returned.
*/
extern LZMA_API(uint64_t) lzma_raw_decoder_memusage(const lzma_filter *filters)
lzma_nothrow lzma_attr_pure;
/**
* \brief Initialize raw encoder
*
* This function may be useful when implementing custom file formats.
*
* \param strm Pointer to properly prepared lzma_stream
* \param filters Array of lzma_filter structures. The end of the
* array must be marked with .id = LZMA_VLI_UNKNOWN.
*
* The `action' with lzma_code() can be LZMA_RUN, LZMA_SYNC_FLUSH (if the
* filter chain supports it), or LZMA_FINISH.
*
* \return - LZMA_OK
* - LZMA_MEM_ERROR
* - LZMA_OPTIONS_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_raw_encoder(
lzma_stream *strm, const lzma_filter *filters)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Initialize raw decoder
*
* The initialization of raw decoder goes similarly to raw encoder.
*
* The `action' with lzma_code() can be LZMA_RUN or LZMA_FINISH. Using
* LZMA_FINISH is not required, it is supported just for convenience.
*
* \return - LZMA_OK
* - LZMA_MEM_ERROR
* - LZMA_OPTIONS_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_raw_decoder(
lzma_stream *strm, const lzma_filter *filters)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Update the filter chain in the encoder
*
* This function is for advanced users only. This function has two slightly
* different purposes:
*
* - After LZMA_FULL_FLUSH when using Stream encoder: Set a new filter
* chain, which will be used starting from the next Block.
*
* - After LZMA_SYNC_FLUSH using Raw, Block, or Stream encoder: Change
* the filter-specific options in the middle of encoding. The actual
* filters in the chain (Filter IDs) cannot be changed. In the future,
* it might become possible to change the filter options without
* using LZMA_SYNC_FLUSH.
*
* While rarely useful, this function may be called also when no data has
* been compressed yet. In that case, this function will behave as if
* LZMA_FULL_FLUSH (Stream encoder) or LZMA_SYNC_FLUSH (Raw or Block
* encoder) had been used right before calling this function.
*
* \return - LZMA_OK
* - LZMA_MEM_ERROR
* - LZMA_MEMLIMIT_ERROR
* - LZMA_OPTIONS_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_filters_update(
lzma_stream *strm, const lzma_filter *filters) lzma_nothrow;
/**
* \brief Single-call raw encoder
*
* \param filters Array of lzma_filter structures. The end of the
* array must be marked with .id = LZMA_VLI_UNKNOWN.
* \param allocator lzma_allocator for custom allocator functions.
* Set to NULL to use malloc() and free().
* \param in Beginning of the input buffer
* \param in_size Size of the input buffer
* \param out Beginning of the output buffer
* \param out_pos The next byte will be written to out[*out_pos].
* *out_pos is updated only if encoding succeeds.
* \param out_size Size of the out buffer; the first byte into
* which no data is written to is out[out_size].
*
* \return - LZMA_OK: Encoding was successful.
* - LZMA_BUF_ERROR: Not enough output buffer space.
* - LZMA_OPTIONS_ERROR
* - LZMA_MEM_ERROR
* - LZMA_DATA_ERROR
* - LZMA_PROG_ERROR
*
* \note There is no function to calculate how big output buffer
* would surely be big enough. (lzma_stream_buffer_bound()
* works only for lzma_stream_buffer_encode(); raw encoder
* won't necessarily meet that bound.)
*/
extern LZMA_API(lzma_ret) lzma_raw_buffer_encode(
const lzma_filter *filters, lzma_allocator *allocator,
const uint8_t *in, size_t in_size, uint8_t *out,
size_t *out_pos, size_t out_size) lzma_nothrow;
/**
* \brief Single-call raw decoder
*
* \param filters Array of lzma_filter structures. The end of the
* array must be marked with .id = LZMA_VLI_UNKNOWN.
* \param allocator lzma_allocator for custom allocator functions.
* Set to NULL to use malloc() and free().
* \param in Beginning of the input buffer
* \param in_pos The next byte will be read from in[*in_pos].
* *in_pos is updated only if decoding succeeds.
* \param in_size Size of the input buffer; the first byte that
* won't be read is in[in_size].
* \param out Beginning of the output buffer
* \param out_pos The next byte will be written to out[*out_pos].
* *out_pos is updated only if encoding succeeds.
* \param out_size Size of the out buffer; the first byte into
* which no data is written to is out[out_size].
*/
extern LZMA_API(lzma_ret) lzma_raw_buffer_decode(
const lzma_filter *filters, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos, size_t in_size,
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
/**
* \brief Get the size of the Filter Properties field
*
* This function may be useful when implementing custom file formats
* using the raw encoder and decoder.
*
* \param size Pointer to uint32_t to hold the size of the properties
* \param filter Filter ID and options (the size of the properties may
* vary depending on the options)
*
* \return - LZMA_OK
* - LZMA_OPTIONS_ERROR
* - LZMA_PROG_ERROR
*
* \note This function validates the Filter ID, but does not
* necessarily validate the options. Thus, it is possible
* that this returns LZMA_OK while the following call to
* lzma_properties_encode() returns LZMA_OPTIONS_ERROR.
*/
extern LZMA_API(lzma_ret) lzma_properties_size(
uint32_t *size, const lzma_filter *filter) lzma_nothrow;
/**
* \brief Encode the Filter Properties field
*
* \param filter Filter ID and options
* \param props Buffer to hold the encoded options. The size of
* buffer must have been already determined with
* lzma_properties_size().
*
* \return - LZMA_OK
* - LZMA_OPTIONS_ERROR
* - LZMA_PROG_ERROR
*
* \note Even this function won't validate more options than actually
* necessary. Thus, it is possible that encoding the properties
* succeeds but using the same options to initialize the encoder
* will fail.
*
* \note If lzma_properties_size() indicated that the size
* of the Filter Properties field is zero, calling
* lzma_properties_encode() is not required, but it
* won't do any harm either.
*/
extern LZMA_API(lzma_ret) lzma_properties_encode(
const lzma_filter *filter, uint8_t *props) lzma_nothrow;
/**
* \brief Decode the Filter Properties field
*
* \param filter filter->id must have been set to the correct
* Filter ID. filter->options doesn't need to be
* initialized (it's not freed by this function). The
* decoded options will be stored to filter->options.
* filter->options is set to NULL if there are no
* properties or if an error occurs.
* \param allocator Custom memory allocator used to allocate the
* options. Set to NULL to use the default malloc(),
* and in case of an error, also free().
* \param props Input buffer containing the properties.
* \param props_size Size of the properties. This must be the exact
* size; giving too much or too little input will
* return LZMA_OPTIONS_ERROR.
*
* \return - LZMA_OK
* - LZMA_OPTIONS_ERROR
* - LZMA_MEM_ERROR
*/
extern LZMA_API(lzma_ret) lzma_properties_decode(
lzma_filter *filter, lzma_allocator *allocator,
const uint8_t *props, size_t props_size) lzma_nothrow;
/**
* \brief Calculate encoded size of a Filter Flags field
*
* Knowing the size of Filter Flags is useful to know when allocating
* memory to hold the encoded Filter Flags.
*
* \param size Pointer to integer to hold the calculated size
* \param filter Filter ID and associated options whose encoded
* size is to be calculated
*
* \return - LZMA_OK: *size set successfully. Note that this doesn't
* guarantee that filter->options is valid, thus
* lzma_filter_flags_encode() may still fail.
* - LZMA_OPTIONS_ERROR: Unknown Filter ID or unsupported options.
* - LZMA_PROG_ERROR: Invalid options
*
* \note If you need to calculate size of List of Filter Flags,
* you need to loop over every lzma_filter entry.
*/
extern LZMA_API(lzma_ret) lzma_filter_flags_size(
uint32_t *size, const lzma_filter *filter)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Encode Filter Flags into given buffer
*
* In contrast to some functions, this doesn't allocate the needed buffer.
* This is due to how this function is used internally by liblzma.
*
* \param filter Filter ID and options to be encoded
* \param out Beginning of the output buffer
* \param out_pos out[*out_pos] is the next write position. This
* is updated by the encoder.
* \param out_size out[out_size] is the first byte to not write.
*
* \return - LZMA_OK: Encoding was successful.
* - LZMA_OPTIONS_ERROR: Invalid or unsupported options.
* - LZMA_PROG_ERROR: Invalid options or not enough output
* buffer space (you should have checked it with
* lzma_filter_flags_size()).
*/
extern LZMA_API(lzma_ret) lzma_filter_flags_encode(const lzma_filter *filter,
uint8_t *out, size_t *out_pos, size_t out_size)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Decode Filter Flags from given buffer
*
* The decoded result is stored into *filter. The old value of
* filter->options is not free()d.
*
* \return - LZMA_OK
* - LZMA_OPTIONS_ERROR
* - LZMA_MEM_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_filter_flags_decode(
lzma_filter *filter, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos, size_t in_size)
lzma_nothrow lzma_attr_warn_unused_result;

View File

@@ -1,55 +0,0 @@
/**
* \file lzma/hardware.h
* \brief Hardware information
*
* Since liblzma can consume a lot of system resources, it also provides
* ways to limit the resource usage. Applications linking against liblzma
* need to do the actual decisions how much resources to let liblzma to use.
* To ease making these decisions, liblzma provides functions to find out
* the relevant capabilities of the underlaying hardware. Currently there
* is only a function to find out the amount of RAM, but in the future there
* will be also a function to detect how many concurrent threads the system
* can run.
*
* \note On some operating systems, these function may temporarily
* load a shared library or open file descriptor(s) to find out
* the requested hardware information. Unless the application
* assumes that specific file descriptors are not touched by
* other threads, this should have no effect on thread safety.
* Possible operations involving file descriptors will restart
* the syscalls if they return EINTR.
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Get the total amount of physical memory (RAM) in bytes
*
* This function may be useful when determining a reasonable memory
* usage limit for decompressing or how much memory it is OK to use
* for compressing.
*
* \return On success, the total amount of physical memory in bytes
* is returned. If the amount of RAM cannot be determined,
* zero is returned. This can happen if an error occurs
* or if there is no code in liblzma to detect the amount
* of RAM on the specific operating system.
*/
extern LZMA_API(uint64_t) lzma_physmem(void) lzma_nothrow;

View File

@@ -1,687 +0,0 @@
/**
* \file lzma/index.h
* \brief Handling of .xz Index and related information
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Opaque data type to hold the Index(es) and other information
*
* lzma_index often holds just one .xz Index and possibly the Stream Flags
* of the same Stream and size of the Stream Padding field. However,
* multiple lzma_indexes can be concatenated with lzma_index_cat() and then
* there may be information about multiple Streams in the same lzma_index.
*
* Notes about thread safety: Only one thread may modify lzma_index at
* a time. All functions that take non-const pointer to lzma_index
* modify it. As long as no thread is modifying the lzma_index, getting
* information from the same lzma_index can be done from multiple threads
* at the same time with functions that take a const pointer to
* lzma_index or use lzma_index_iter. The same iterator must be used
* only by one thread at a time, of course, but there can be as many
* iterators for the same lzma_index as needed.
*/
typedef struct lzma_index_s lzma_index;
/**
* \brief Iterator to get information about Blocks and Streams
*/
typedef struct {
struct {
/**
* \brief Pointer to Stream Flags
*
* This is NULL if Stream Flags have not been set for
* this Stream with lzma_index_stream_flags().
*/
const lzma_stream_flags *flags;
const void *reserved_ptr1;
const void *reserved_ptr2;
const void *reserved_ptr3;
/**
* \brief Stream number in the lzma_index
*
* The first Stream is 1.
*/
lzma_vli number;
/**
* \brief Number of Blocks in the Stream
*
* If this is zero, the block structure below has
* undefined values.
*/
lzma_vli block_count;
/**
* \brief Compressed start offset of this Stream
*
* The offset is relative to the beginning of the lzma_index
* (i.e. usually the beginning of the .xz file).
*/
lzma_vli compressed_offset;
/**
* \brief Uncompressed start offset of this Stream
*
* The offset is relative to the beginning of the lzma_index
* (i.e. usually the beginning of the .xz file).
*/
lzma_vli uncompressed_offset;
/**
* \brief Compressed size of this Stream
*
* This includes all headers except the possible
* Stream Padding after this Stream.
*/
lzma_vli compressed_size;
/**
* \brief Uncompressed size of this Stream
*/
lzma_vli uncompressed_size;
/**
* \brief Size of Stream Padding after this Stream
*
* If it hasn't been set with lzma_index_stream_padding(),
* this defaults to zero. Stream Padding is always
* a multiple of four bytes.
*/
lzma_vli padding;
lzma_vli reserved_vli1;
lzma_vli reserved_vli2;
lzma_vli reserved_vli3;
lzma_vli reserved_vli4;
} stream;
struct {
/**
* \brief Block number in the file
*
* The first Block is 1.
*/
lzma_vli number_in_file;
/**
* \brief Compressed start offset of this Block
*
* This offset is relative to the beginning of the
* lzma_index (i.e. usually the beginning of the .xz file).
* Normally this is where you should seek in the .xz file
* to start decompressing this Block.
*/
lzma_vli compressed_file_offset;
/**
* \brief Uncompressed start offset of this Block
*
* This offset is relative to the beginning of the lzma_index
* (i.e. usually the beginning of the .xz file).
*
* When doing random-access reading, it is possible that
* the target offset is not exactly at Block boundary. One
* will need to compare the target offset against
* uncompressed_file_offset or uncompressed_stream_offset,
* and possibly decode and throw away some amount of data
* before reaching the target offset.
*/
lzma_vli uncompressed_file_offset;
/**
* \brief Block number in this Stream
*
* The first Block is 1.
*/
lzma_vli number_in_stream;
/**
* \brief Compressed start offset of this Block
*
* This offset is relative to the beginning of the Stream
* containing this Block.
*/
lzma_vli compressed_stream_offset;
/**
* \brief Uncompressed start offset of this Block
*
* This offset is relative to the beginning of the Stream
* containing this Block.
*/
lzma_vli uncompressed_stream_offset;
/**
* \brief Uncompressed size of this Block
*
* You should pass this to the Block decoder if you will
* decode this Block. It will allow the Block decoder to
* validate the uncompressed size.
*/
lzma_vli uncompressed_size;
/**
* \brief Unpadded size of this Block
*
* You should pass this to the Block decoder if you will
* decode this Block. It will allow the Block decoder to
* validate the unpadded size.
*/
lzma_vli unpadded_size;
/**
* \brief Total compressed size
*
* This includes all headers and padding in this Block.
* This is useful if you need to know how many bytes
* the Block decoder will actually read.
*/
lzma_vli total_size;
lzma_vli reserved_vli1;
lzma_vli reserved_vli2;
lzma_vli reserved_vli3;
lzma_vli reserved_vli4;
const void *reserved_ptr1;
const void *reserved_ptr2;
const void *reserved_ptr3;
const void *reserved_ptr4;
} block;
/*
* Internal data which is used to store the state of the iterator.
* The exact format may vary between liblzma versions, so don't
* touch these in any way.
*/
union {
const void *p;
size_t s;
lzma_vli v;
} internal[6];
} lzma_index_iter;
/**
* \brief Operation mode for lzma_index_iter_next()
*/
typedef enum {
LZMA_INDEX_ITER_ANY = 0,
/**<
* \brief Get the next Block or Stream
*
* Go to the next Block if the current Stream has at least
* one Block left. Otherwise go to the next Stream even if
* it has no Blocks. If the Stream has no Blocks
* (lzma_index_iter.stream.block_count == 0),
* lzma_index_iter.block will have undefined values.
*/
LZMA_INDEX_ITER_STREAM = 1,
/**<
* \brief Get the next Stream
*
* Go to the next Stream even if the current Stream has
* unread Blocks left. If the next Stream has at least one
* Block, the iterator will point to the first Block.
* If there are no Blocks, lzma_index_iter.block will have
* undefined values.
*/
LZMA_INDEX_ITER_BLOCK = 2,
/**<
* \brief Get the next Block
*
* Go to the next Block if the current Stream has at least
* one Block left. If the current Stream has no Blocks left,
* the next Stream with at least one Block is located and
* the iterator will be made to point to the first Block of
* that Stream.
*/
LZMA_INDEX_ITER_NONEMPTY_BLOCK = 3
/**<
* \brief Get the next non-empty Block
*
* This is like LZMA_INDEX_ITER_BLOCK except that it will
* skip Blocks whose Uncompressed Size is zero.
*/
} lzma_index_iter_mode;
/**
* \brief Calculate memory usage of lzma_index
*
* On disk, the size of the Index field depends on both the number of Records
* stored and how big values the Records store (due to variable-length integer
* encoding). When the Index is kept in lzma_index structure, the memory usage
* depends only on the number of Records/Blocks stored in the Index(es), and
* in case of concatenated lzma_indexes, the number of Streams. The size in
* RAM is almost always significantly bigger than in the encoded form on disk.
*
* This function calculates an approximate amount of memory needed hold
* the given number of Streams and Blocks in lzma_index structure. This
* value may vary between CPU architectures and also between liblzma versions
* if the internal implementation is modified.
*/
extern LZMA_API(uint64_t) lzma_index_memusage(
lzma_vli streams, lzma_vli blocks) lzma_nothrow;
/**
* \brief Calculate the memory usage of an existing lzma_index
*
* This is a shorthand for lzma_index_memusage(lzma_index_stream_count(i),
* lzma_index_block_count(i)).
*/
extern LZMA_API(uint64_t) lzma_index_memused(const lzma_index *i)
lzma_nothrow;
/**
* \brief Allocate and initialize a new lzma_index structure
*
* \return On success, a pointer to an empty initialized lzma_index is
* returned. If allocation fails, NULL is returned.
*/
extern LZMA_API(lzma_index *) lzma_index_init(lzma_allocator *allocator)
lzma_nothrow;
/**
* \brief Deallocate lzma_index
*
* If i is NULL, this does nothing.
*/
extern LZMA_API(void) lzma_index_end(lzma_index *i, lzma_allocator *allocator)
lzma_nothrow;
/**
* \brief Add a new Block to lzma_index
*
* \param i Pointer to a lzma_index structure
* \param allocator Pointer to lzma_allocator, or NULL to
* use malloc()
* \param unpadded_size Unpadded Size of a Block. This can be
* calculated with lzma_block_unpadded_size()
* after encoding or decoding the Block.
* \param uncompressed_size Uncompressed Size of a Block. This can be
* taken directly from lzma_block structure
* after encoding or decoding the Block.
*
* Appending a new Block does not invalidate iterators. For example,
* if an iterator was pointing to the end of the lzma_index, after
* lzma_index_append() it is possible to read the next Block with
* an existing iterator.
*
* \return - LZMA_OK
* - LZMA_MEM_ERROR
* - LZMA_DATA_ERROR: Compressed or uncompressed size of the
* Stream or size of the Index field would grow too big.
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_index_append(
lzma_index *i, lzma_allocator *allocator,
lzma_vli unpadded_size, lzma_vli uncompressed_size)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Set the Stream Flags
*
* Set the Stream Flags of the last (and typically the only) Stream
* in lzma_index. This can be useful when reading information from the
* lzma_index, because to decode Blocks, knowing the integrity check type
* is needed.
*
* The given Stream Flags are copied into internal preallocated structure
* in the lzma_index, thus the caller doesn't need to keep the *stream_flags
* available after calling this function.
*
* \return - LZMA_OK
* - LZMA_OPTIONS_ERROR: Unsupported stream_flags->version.
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_index_stream_flags(
lzma_index *i, const lzma_stream_flags *stream_flags)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Get the types of integrity Checks
*
* If lzma_index_stream_flags() is used to set the Stream Flags for
* every Stream, lzma_index_checks() can be used to get a bitmask to
* indicate which Check types have been used. It can be useful e.g. if
* showing the Check types to the user.
*
* The bitmask is 1 << check_id, e.g. CRC32 is 1 << 1 and SHA-256 is 1 << 10.
*/
extern LZMA_API(uint32_t) lzma_index_checks(const lzma_index *i)
lzma_nothrow lzma_attr_pure;
/**
* \brief Set the amount of Stream Padding
*
* Set the amount of Stream Padding of the last (and typically the only)
* Stream in the lzma_index. This is needed when planning to do random-access
* reading within multiple concatenated Streams.
*
* By default, the amount of Stream Padding is assumed to be zero bytes.
*
* \return - LZMA_OK
* - LZMA_DATA_ERROR: The file size would grow too big.
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_index_stream_padding(
lzma_index *i, lzma_vli stream_padding)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Get the number of Streams
*/
extern LZMA_API(lzma_vli) lzma_index_stream_count(const lzma_index *i)
lzma_nothrow lzma_attr_pure;
/**
* \brief Get the number of Blocks
*
* This returns the total number of Blocks in lzma_index. To get number
* of Blocks in individual Streams, use lzma_index_iter.
*/
extern LZMA_API(lzma_vli) lzma_index_block_count(const lzma_index *i)
lzma_nothrow lzma_attr_pure;
/**
* \brief Get the size of the Index field as bytes
*
* This is needed to verify the Backward Size field in the Stream Footer.
*/
extern LZMA_API(lzma_vli) lzma_index_size(const lzma_index *i)
lzma_nothrow lzma_attr_pure;
/**
* \brief Get the total size of the Stream
*
* If multiple lzma_indexes have been combined, this works as if the Blocks
* were in a single Stream. This is useful if you are going to combine
* Blocks from multiple Streams into a single new Stream.
*/
extern LZMA_API(lzma_vli) lzma_index_stream_size(const lzma_index *i)
lzma_nothrow lzma_attr_pure;
/**
* \brief Get the total size of the Blocks
*
* This doesn't include the Stream Header, Stream Footer, Stream Padding,
* or Index fields.
*/
extern LZMA_API(lzma_vli) lzma_index_total_size(const lzma_index *i)
lzma_nothrow lzma_attr_pure;
/**
* \brief Get the total size of the file
*
* When no lzma_indexes have been combined with lzma_index_cat() and there is
* no Stream Padding, this function is identical to lzma_index_stream_size().
* If multiple lzma_indexes have been combined, this includes also the headers
* of each separate Stream and the possible Stream Padding fields.
*/
extern LZMA_API(lzma_vli) lzma_index_file_size(const lzma_index *i)
lzma_nothrow lzma_attr_pure;
/**
* \brief Get the uncompressed size of the file
*/
extern LZMA_API(lzma_vli) lzma_index_uncompressed_size(const lzma_index *i)
lzma_nothrow lzma_attr_pure;
/**
* \brief Initialize an iterator
*
* \param iter Pointer to a lzma_index_iter structure
* \param i lzma_index to which the iterator will be associated
*
* This function associates the iterator with the given lzma_index, and calls
* lzma_index_iter_rewind() on the iterator.
*
* This function doesn't allocate any memory, thus there is no
* lzma_index_iter_end(). The iterator is valid as long as the
* associated lzma_index is valid, that is, until lzma_index_end() or
* using it as source in lzma_index_cat(). Specifically, lzma_index doesn't
* become invalid if new Blocks are added to it with lzma_index_append() or
* if it is used as the destination in lzma_index_cat().
*
* It is safe to make copies of an initialized lzma_index_iter, for example,
* to easily restart reading at some particular position.
*/
extern LZMA_API(void) lzma_index_iter_init(
lzma_index_iter *iter, const lzma_index *i) lzma_nothrow;
/**
* \brief Rewind the iterator
*
* Rewind the iterator so that next call to lzma_index_iter_next() will
* return the first Block or Stream.
*/
extern LZMA_API(void) lzma_index_iter_rewind(lzma_index_iter *iter)
lzma_nothrow;
/**
* \brief Get the next Block or Stream
*
* \param iter Iterator initialized with lzma_index_iter_init()
* \param mode Specify what kind of information the caller wants
* to get. See lzma_index_iter_mode for details.
*
* \return If next Block or Stream matching the mode was found, *iter
* is updated and this function returns false. If no Block or
* Stream matching the mode is found, *iter is not modified
* and this function returns true. If mode is set to an unknown
* value, *iter is not modified and this function returns true.
*/
extern LZMA_API(lzma_bool) lzma_index_iter_next(
lzma_index_iter *iter, lzma_index_iter_mode mode)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Locate a Block
*
* If it is possible to seek in the .xz file, it is possible to parse
* the Index field(s) and use lzma_index_iter_locate() to do random-access
* reading with granularity of Block size.
*
* \param iter Iterator that was earlier initialized with
* lzma_index_iter_init().
* \param target Uncompressed target offset which the caller would
* like to locate from the Stream
*
* If the target is smaller than the uncompressed size of the Stream (can be
* checked with lzma_index_uncompressed_size()):
* - Information about the Stream and Block containing the requested
* uncompressed offset is stored into *iter.
* - Internal state of the iterator is adjusted so that
* lzma_index_iter_next() can be used to read subsequent Blocks or Streams.
* - This function returns false.
*
* If target is greater than the uncompressed size of the Stream, *iter
* is not modified, and this function returns true.
*/
extern LZMA_API(lzma_bool) lzma_index_iter_locate(
lzma_index_iter *iter, lzma_vli target) lzma_nothrow;
/**
* \brief Concatenate lzma_indexes
*
* Concatenating lzma_indexes is useful when doing random-access reading in
* multi-Stream .xz file, or when combining multiple Streams into single
* Stream.
*
* \param dest lzma_index after which src is appended
* \param src lzma_index to be appended after dest. If this
* function succeeds, the memory allocated for src
* is freed or moved to be part of dest, and all
* iterators pointing to src will become invalid.
* \param allocator Custom memory allocator; can be NULL to use
* malloc() and free().
*
* \return - LZMA_OK: lzma_indexes were concatenated successfully.
* src is now a dangling pointer.
* - LZMA_DATA_ERROR: *dest would grow too big.
* - LZMA_MEM_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_index_cat(
lzma_index *dest, lzma_index *src, lzma_allocator *allocator)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Duplicate lzma_index
*
* \return A copy of the lzma_index, or NULL if memory allocation failed.
*/
extern LZMA_API(lzma_index *) lzma_index_dup(
const lzma_index *i, lzma_allocator *allocator)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Initialize .xz Index encoder
*
* \param strm Pointer to properly prepared lzma_stream
* \param i Pointer to lzma_index which should be encoded.
*
* The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.
* It is enough to use only one of them (you can choose freely; use LZMA_RUN
* to support liblzma versions older than 5.0.0).
*
* \return - LZMA_OK: Initialization succeeded, continue with lzma_code().
* - LZMA_MEM_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_index_encoder(
lzma_stream *strm, const lzma_index *i)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Initialize .xz Index decoder
*
* \param strm Pointer to properly prepared lzma_stream
* \param i The decoded Index will be made available via
* this pointer. Initially this function will
* set *i to NULL (the old value is ignored). If
* decoding succeeds (lzma_code() returns
* LZMA_STREAM_END), *i will be set to point
* to a new lzma_index, which the application
* has to later free with lzma_index_end().
* \param memlimit How much memory the resulting lzma_index is
* allowed to require.
*
* The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.
* It is enough to use only one of them (you can choose freely; use LZMA_RUN
* to support liblzma versions older than 5.0.0).
*
* \return - LZMA_OK: Initialization succeeded, continue with lzma_code().
* - LZMA_MEM_ERROR
* - LZMA_MEMLIMIT_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_index_decoder(
lzma_stream *strm, lzma_index **i, uint64_t memlimit)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Single-call .xz Index encoder
*
* \param i lzma_index to be encoded
* \param out Beginning of the output buffer
* \param out_pos The next byte will be written to out[*out_pos].
* *out_pos is updated only if encoding succeeds.
* \param out_size Size of the out buffer; the first byte into
* which no data is written to is out[out_size].
*
* \return - LZMA_OK: Encoding was successful.
* - LZMA_BUF_ERROR: Output buffer is too small. Use
* lzma_index_size() to find out how much output
* space is needed.
* - LZMA_PROG_ERROR
*
* \note This function doesn't take allocator argument since all
* the internal data is allocated on stack.
*/
extern LZMA_API(lzma_ret) lzma_index_buffer_encode(const lzma_index *i,
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
/**
* \brief Single-call .xz Index decoder
*
* \param i If decoding succeeds, *i will point to a new
* lzma_index, which the application has to
* later free with lzma_index_end(). If an error
* occurs, *i will be NULL. The old value of *i
* is always ignored and thus doesn't need to be
* initialized by the caller.
* \param memlimit Pointer to how much memory the resulting
* lzma_index is allowed to require. The value
* pointed by this pointer is modified if and only
* if LZMA_MEMLIMIT_ERROR is returned.
* \param allocator Pointer to lzma_allocator, or NULL to use malloc()
* \param in Beginning of the input buffer
* \param in_pos The next byte will be read from in[*in_pos].
* *in_pos is updated only if decoding succeeds.
* \param in_size Size of the input buffer; the first byte that
* won't be read is in[in_size].
*
* \return - LZMA_OK: Decoding was successful.
* - LZMA_MEM_ERROR
* - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.
* The minimum required memlimit value was stored to *memlimit.
* - LZMA_DATA_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,
uint64_t *memlimit, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos, size_t in_size)
lzma_nothrow;

View File

@@ -1,112 +0,0 @@
/**
* \file lzma/index_hash.h
* \brief Validate Index by using a hash function
*
* Hashing makes it possible to use constant amount of memory to validate
* Index of arbitrary size.
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Opaque data type to hold the Index hash
*/
typedef struct lzma_index_hash_s lzma_index_hash;
/**
* \brief Allocate and initialize a new lzma_index_hash structure
*
* If index_hash is NULL, a new lzma_index_hash structure is allocated,
* initialized, and a pointer to it returned. If allocation fails, NULL
* is returned.
*
* If index_hash is non-NULL, it is reinitialized and the same pointer
* returned. In this case, return value cannot be NULL or a different
* pointer than the index_hash that was given as an argument.
*/
extern LZMA_API(lzma_index_hash *) lzma_index_hash_init(
lzma_index_hash *index_hash, lzma_allocator *allocator)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Deallocate lzma_index_hash structure
*/
extern LZMA_API(void) lzma_index_hash_end(
lzma_index_hash *index_hash, lzma_allocator *allocator)
lzma_nothrow;
/**
* \brief Add a new Record to an Index hash
*
* \param index Pointer to a lzma_index_hash structure
* \param unpadded_size Unpadded Size of a Block
* \param uncompressed_size Uncompressed Size of a Block
*
* \return - LZMA_OK
* - LZMA_DATA_ERROR: Compressed or uncompressed size of the
* Stream or size of the Index field would grow too big.
* - LZMA_PROG_ERROR: Invalid arguments or this function is being
* used when lzma_index_hash_decode() has already been used.
*/
extern LZMA_API(lzma_ret) lzma_index_hash_append(lzma_index_hash *index_hash,
lzma_vli unpadded_size, lzma_vli uncompressed_size)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Decode and validate the Index field
*
* After telling the sizes of all Blocks with lzma_index_hash_append(),
* the actual Index field is decoded with this function. Specifically,
* once decoding of the Index field has been started, no more Records
* can be added using lzma_index_hash_append().
*
* This function doesn't use lzma_stream structure to pass the input data.
* Instead, the input buffer is specified using three arguments. This is
* because it matches better the internal APIs of liblzma.
*
* \param index_hash Pointer to a lzma_index_hash structure
* \param in Pointer to the beginning of the input buffer
* \param in_pos in[*in_pos] is the next byte to process
* \param in_size in[in_size] is the first byte not to process
*
* \return - LZMA_OK: So far good, but more input is needed.
* - LZMA_STREAM_END: Index decoded successfully and it matches
* the Records given with lzma_index_hash_append().
* - LZMA_DATA_ERROR: Index is corrupt or doesn't match the
* information given with lzma_index_hash_append().
* - LZMA_BUF_ERROR: Cannot progress because *in_pos >= in_size.
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_index_hash_decode(lzma_index_hash *index_hash,
const uint8_t *in, size_t *in_pos, size_t in_size)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Get the size of the Index field as bytes
*
* This is needed to verify the Backward Size field in the Stream Footer.
*/
extern LZMA_API(lzma_vli) lzma_index_hash_size(
const lzma_index_hash *index_hash)
lzma_nothrow lzma_attr_pure;

View File

@@ -1,425 +0,0 @@
/**
* \file lzma/lzma.h
* \brief LZMA1 and LZMA2 filters
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief LZMA1 Filter ID
*
* LZMA1 is the very same thing as what was called just LZMA in LZMA Utils,
* 7-Zip, and LZMA SDK. It's called LZMA1 here to prevent developers from
* accidentally using LZMA when they actually want LZMA2.
*
* LZMA1 shouldn't be used for new applications unless you _really_ know
* what you are doing. LZMA2 is almost always a better choice.
*/
#define LZMA_FILTER_LZMA1 LZMA_VLI_C(0x4000000000000001)
/**
* \brief LZMA2 Filter ID
*
* Usually you want this instead of LZMA1. Compared to LZMA1, LZMA2 adds
* support for LZMA_SYNC_FLUSH, uncompressed chunks (smaller expansion
* when trying to compress uncompressible data), possibility to change
* lc/lp/pb in the middle of encoding, and some other internal improvements.
*/
#define LZMA_FILTER_LZMA2 LZMA_VLI_C(0x21)
/**
* \brief Match finders
*
* Match finder has major effect on both speed and compression ratio.
* Usually hash chains are faster than binary trees.
*
* If you will use LZMA_SYNC_FLUSH often, the hash chains may be a better
* choice, because binary trees get much higher compression ratio penalty
* with LZMA_SYNC_FLUSH.
*
* The memory usage formulas are only rough estimates, which are closest to
* reality when dict_size is a power of two. The formulas are more complex
* in reality, and can also change a little between liblzma versions. Use
* lzma_raw_encoder_memusage() to get more accurate estimate of memory usage.
*/
typedef enum {
LZMA_MF_HC3 = 0x03,
/**<
* \brief Hash Chain with 2- and 3-byte hashing
*
* Minimum nice_len: 3
*
* Memory usage:
* - dict_size <= 16 MiB: dict_size * 7.5
* - dict_size > 16 MiB: dict_size * 5.5 + 64 MiB
*/
LZMA_MF_HC4 = 0x04,
/**<
* \brief Hash Chain with 2-, 3-, and 4-byte hashing
*
* Minimum nice_len: 4
*
* Memory usage:
* - dict_size <= 32 MiB: dict_size * 7.5
* - dict_size > 32 MiB: dict_size * 6.5
*/
LZMA_MF_BT2 = 0x12,
/**<
* \brief Binary Tree with 2-byte hashing
*
* Minimum nice_len: 2
*
* Memory usage: dict_size * 9.5
*/
LZMA_MF_BT3 = 0x13,
/**<
* \brief Binary Tree with 2- and 3-byte hashing
*
* Minimum nice_len: 3
*
* Memory usage:
* - dict_size <= 16 MiB: dict_size * 11.5
* - dict_size > 16 MiB: dict_size * 9.5 + 64 MiB
*/
LZMA_MF_BT4 = 0x14
/**<
* \brief Binary Tree with 2-, 3-, and 4-byte hashing
*
* Minimum nice_len: 4
*
* Memory usage:
* - dict_size <= 32 MiB: dict_size * 11.5
* - dict_size > 32 MiB: dict_size * 10.5
*/
} lzma_match_finder;
/**
* \brief Test if given match finder is supported
*
* Return true if the given match finder is supported by this liblzma build.
* Otherwise false is returned. It is safe to call this with a value that
* isn't listed in lzma_match_finder enumeration; the return value will be
* false.
*
* There is no way to list which match finders are available in this
* particular liblzma version and build. It would be useless, because
* a new match finder, which the application developer wasn't aware,
* could require giving additional options to the encoder that the older
* match finders don't need.
*/
extern LZMA_API(lzma_bool) lzma_mf_is_supported(lzma_match_finder match_finder)
lzma_nothrow lzma_attr_const;
/**
* \brief Compression modes
*
* This selects the function used to analyze the data produced by the match
* finder.
*/
typedef enum {
LZMA_MODE_FAST = 1,
/**<
* \brief Fast compression
*
* Fast mode is usually at its best when combined with
* a hash chain match finder.
*/
LZMA_MODE_NORMAL = 2
/**<
* \brief Normal compression
*
* This is usually notably slower than fast mode. Use this
* together with binary tree match finders to expose the
* full potential of the LZMA1 or LZMA2 encoder.
*/
} lzma_mode;
/**
* \brief Test if given compression mode is supported
*
* Return true if the given compression mode is supported by this liblzma
* build. Otherwise false is returned. It is safe to call this with a value
* that isn't listed in lzma_mode enumeration; the return value will be false.
*
* There is no way to list which modes are available in this particular
* liblzma version and build. It would be useless, because a new compression
* mode, which the application developer wasn't aware, could require giving
* additional options to the encoder that the older modes don't need.
*/
extern LZMA_API(lzma_bool) lzma_mode_is_supported(lzma_mode mode)
lzma_nothrow lzma_attr_const;
/**
* \brief Options specific to the LZMA1 and LZMA2 filters
*
* Since LZMA1 and LZMA2 share most of the code, it's simplest to share
* the options structure too. For encoding, all but the reserved variables
* need to be initialized unless specifically mentioned otherwise.
* lzma_lzma_preset() can be used to get a good starting point.
*
* For raw decoding, both LZMA1 and LZMA2 need dict_size, preset_dict, and
* preset_dict_size (if preset_dict != NULL). LZMA1 needs also lc, lp, and pb.
*/
typedef struct {
/**
* \brief Dictionary size in bytes
*
* Dictionary size indicates how many bytes of the recently processed
* uncompressed data is kept in memory. One method to reduce size of
* the uncompressed data is to store distance-length pairs, which
* indicate what data to repeat from the dictionary buffer. Thus,
* the bigger the dictionary, the better the compression ratio
* usually is.
*
* Maximum size of the dictionary depends on multiple things:
* - Memory usage limit
* - Available address space (not a problem on 64-bit systems)
* - Selected match finder (encoder only)
*
* Currently the maximum dictionary size for encoding is 1.5 GiB
* (i.e. (UINT32_C(1) << 30) + (UINT32_C(1) << 29)) even on 64-bit
* systems for certain match finder implementation reasons. In the
* future, there may be match finders that support bigger
* dictionaries.
*
* Decoder already supports dictionaries up to 4 GiB - 1 B (i.e.
* UINT32_MAX), so increasing the maximum dictionary size of the
* encoder won't cause problems for old decoders.
*
* Because extremely small dictionaries sizes would have unneeded
* overhead in the decoder, the minimum dictionary size is 4096 bytes.
*
* \note When decoding, too big dictionary does no other harm
* than wasting memory.
*/
uint32_t dict_size;
# define LZMA_DICT_SIZE_MIN UINT32_C(4096)
# define LZMA_DICT_SIZE_DEFAULT (UINT32_C(1) << 23)
/**
* \brief Pointer to an initial dictionary
*
* It is possible to initialize the LZ77 history window using
* a preset dictionary. It is useful when compressing many
* similar, relatively small chunks of data independently from
* each other. The preset dictionary should contain typical
* strings that occur in the files being compressed. The most
* probable strings should be near the end of the preset dictionary.
*
* This feature should be used only in special situations. For
* now, it works correctly only with raw encoding and decoding.
* Currently none of the container formats supported by
* liblzma allow preset dictionary when decoding, thus if
* you create a .xz or .lzma file with preset dictionary, it
* cannot be decoded with the regular decoder functions. In the
* future, the .xz format will likely get support for preset
* dictionary though.
*/
const uint8_t *preset_dict;
/**
* \brief Size of the preset dictionary
*
* Specifies the size of the preset dictionary. If the size is
* bigger than dict_size, only the last dict_size bytes are
* processed.
*
* This variable is read only when preset_dict is not NULL.
* If preset_dict is not NULL but preset_dict_size is zero,
* no preset dictionary is used (identical to only setting
* preset_dict to NULL).
*/
uint32_t preset_dict_size;
/**
* \brief Number of literal context bits
*
* How many of the highest bits of the previous uncompressed
* eight-bit byte (also known as `literal') are taken into
* account when predicting the bits of the next literal.
*
* E.g. in typical English text, an upper-case letter is
* often followed by a lower-case letter, and a lower-case
* letter is usually followed by another lower-case letter.
* In the US-ASCII character set, the highest three bits are 010
* for upper-case letters and 011 for lower-case letters.
* When lc is at least 3, the literal coding can take advantage of
* this property in the uncompressed data.
*
* There is a limit that applies to literal context bits and literal
* position bits together: lc + lp <= 4. Without this limit the
* decoding could become very slow, which could have security related
* results in some cases like email servers doing virus scanning.
* This limit also simplifies the internal implementation in liblzma.
*
* There may be LZMA1 streams that have lc + lp > 4 (maximum possible
* lc would be 8). It is not possible to decode such streams with
* liblzma.
*/
uint32_t lc;
# define LZMA_LCLP_MIN 0
# define LZMA_LCLP_MAX 4
# define LZMA_LC_DEFAULT 3
/**
* \brief Number of literal position bits
*
* lp affects what kind of alignment in the uncompressed data is
* assumed when encoding literals. A literal is a single 8-bit byte.
* See pb below for more information about alignment.
*/
uint32_t lp;
# define LZMA_LP_DEFAULT 0
/**
* \brief Number of position bits
*
* pb affects what kind of alignment in the uncompressed data is
* assumed in general. The default means four-byte alignment
* (2^ pb =2^2=4), which is often a good choice when there's
* no better guess.
*
* When the aligment is known, setting pb accordingly may reduce
* the file size a little. E.g. with text files having one-byte
* alignment (US-ASCII, ISO-8859-*, UTF-8), setting pb=0 can
* improve compression slightly. For UTF-16 text, pb=1 is a good
* choice. If the alignment is an odd number like 3 bytes, pb=0
* might be the best choice.
*
* Even though the assumed alignment can be adjusted with pb and
* lp, LZMA1 and LZMA2 still slightly favor 16-byte alignment.
* It might be worth taking into account when designing file formats
* that are likely to be often compressed with LZMA1 or LZMA2.
*/
uint32_t pb;
# define LZMA_PB_MIN 0
# define LZMA_PB_MAX 4
# define LZMA_PB_DEFAULT 2
/** Compression mode */
lzma_mode mode;
/**
* \brief Nice length of a match
*
* This determines how many bytes the encoder compares from the match
* candidates when looking for the best match. Once a match of at
* least nice_len bytes long is found, the encoder stops looking for
* better candidates and encodes the match. (Naturally, if the found
* match is actually longer than nice_len, the actual length is
* encoded; it's not truncated to nice_len.)
*
* Bigger values usually increase the compression ratio and
* compression time. For most files, 32 to 128 is a good value,
* which gives very good compression ratio at good speed.
*
* The exact minimum value depends on the match finder. The maximum
* is 273, which is the maximum length of a match that LZMA1 and
* LZMA2 can encode.
*/
uint32_t nice_len;
/** Match finder ID */
lzma_match_finder mf;
/**
* \brief Maximum search depth in the match finder
*
* For every input byte, match finder searches through the hash chain
* or binary tree in a loop, each iteration going one step deeper in
* the chain or tree. The searching stops if
* - a match of at least nice_len bytes long is found;
* - all match candidates from the hash chain or binary tree have
* been checked; or
* - maximum search depth is reached.
*
* Maximum search depth is needed to prevent the match finder from
* wasting too much time in case there are lots of short match
* candidates. On the other hand, stopping the search before all
* candidates have been checked can reduce compression ratio.
*
* Setting depth to zero tells liblzma to use an automatic default
* value, that depends on the selected match finder and nice_len.
* The default is in the range [4, 200] or so (it may vary between
* liblzma versions).
*
* Using a bigger depth value than the default can increase
* compression ratio in some cases. There is no strict maximum value,
* but high values (thousands or millions) should be used with care:
* the encoder could remain fast enough with typical input, but
* malicious input could cause the match finder to slow down
* dramatically, possibly creating a denial of service attack.
*/
uint32_t depth;
/*
* Reserved space to allow possible future extensions without
* breaking the ABI. You should not touch these, because the names
* of these variables may change. These are and will never be used
* with the currently supported options, so it is safe to leave these
* uninitialized.
*/
uint32_t reserved_int1;
uint32_t reserved_int2;
uint32_t reserved_int3;
uint32_t reserved_int4;
uint32_t reserved_int5;
uint32_t reserved_int6;
uint32_t reserved_int7;
uint32_t reserved_int8;
lzma_reserved_enum reserved_enum1;
lzma_reserved_enum reserved_enum2;
lzma_reserved_enum reserved_enum3;
lzma_reserved_enum reserved_enum4;
void *reserved_ptr1;
void *reserved_ptr2;
} lzma_options_lzma;
/**
* \brief Set a compression preset to lzma_options_lzma structure
*
* 0 is the fastest and 9 is the slowest. These match the switches -0 .. -9
* of the xz command line tool. In addition, it is possible to bitwise-or
* flags to the preset. Currently only LZMA_PRESET_EXTREME is supported.
* The flags are defined in container.h, because the flags are used also
* with lzma_easy_encoder().
*
* The preset values are subject to changes between liblzma versions.
*
* This function is available only if LZMA1 or LZMA2 encoder has been enabled
* when building liblzma.
*
* \return On success, false is returned. If the preset is not
* supported, true is returned.
*/
extern LZMA_API(lzma_bool) lzma_lzma_preset(
lzma_options_lzma *options, uint32_t preset) lzma_nothrow;

View File

@@ -1,228 +0,0 @@
/**
* \file lzma/stream_flags.h
* \brief .xz Stream Header and Stream Footer encoder and decoder
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Size of Stream Header and Stream Footer
*
* Stream Header and Stream Footer have the same size and they are not
* going to change even if a newer version of the .xz file format is
* developed in future.
*/
#define LZMA_STREAM_HEADER_SIZE 12
/**
* \brief Options for encoding/decoding Stream Header and Stream Footer
*/
typedef struct {
/**
* \brief Stream Flags format version
*
* To prevent API and ABI breakages if new features are needed in
* Stream Header or Stream Footer, a version number is used to
* indicate which fields in this structure are in use. For now,
* version must always be zero. With non-zero version, the
* lzma_stream_header_encode() and lzma_stream_footer_encode()
* will return LZMA_OPTIONS_ERROR.
*
* lzma_stream_header_decode() and lzma_stream_footer_decode()
* will always set this to the lowest value that supports all the
* features indicated by the Stream Flags field. The application
* must check that the version number set by the decoding functions
* is supported by the application. Otherwise it is possible that
* the application will decode the Stream incorrectly.
*/
uint32_t version;
/**
* \brief Backward Size
*
* Backward Size must be a multiple of four bytes. In this Stream
* format version, Backward Size is the size of the Index field.
*
* Backward Size isn't actually part of the Stream Flags field, but
* it is convenient to include in this structure anyway. Backward
* Size is present only in the Stream Footer. There is no need to
* initialize backward_size when encoding Stream Header.
*
* lzma_stream_header_decode() always sets backward_size to
* LZMA_VLI_UNKNOWN so that it is convenient to use
* lzma_stream_flags_compare() when both Stream Header and Stream
* Footer have been decoded.
*/
lzma_vli backward_size;
# define LZMA_BACKWARD_SIZE_MIN 4
# define LZMA_BACKWARD_SIZE_MAX (LZMA_VLI_C(1) << 34)
/**
* \brief Check ID
*
* This indicates the type of the integrity check calculated from
* uncompressed data.
*/
lzma_check check;
/*
* Reserved space to allow possible future extensions without
* breaking the ABI. You should not touch these, because the
* names of these variables may change.
*
* (We will never be able to use all of these since Stream Flags
* is just two bytes plus Backward Size of four bytes. But it's
* nice to have the proper types when they are needed.)
*/
lzma_reserved_enum reserved_enum1;
lzma_reserved_enum reserved_enum2;
lzma_reserved_enum reserved_enum3;
lzma_reserved_enum reserved_enum4;
lzma_bool reserved_bool1;
lzma_bool reserved_bool2;
lzma_bool reserved_bool3;
lzma_bool reserved_bool4;
lzma_bool reserved_bool5;
lzma_bool reserved_bool6;
lzma_bool reserved_bool7;
lzma_bool reserved_bool8;
uint32_t reserved_int1;
uint32_t reserved_int2;
} lzma_stream_flags;
/**
* \brief Encode Stream Header
*
* \param options Stream Header options to be encoded.
* options->backward_size is ignored and doesn't
* need to be initialized.
* \param out Beginning of the output buffer of
* LZMA_STREAM_HEADER_SIZE bytes.
*
* \return - LZMA_OK: Encoding was successful.
* - LZMA_OPTIONS_ERROR: options->version is not supported by
* this liblzma version.
* - LZMA_PROG_ERROR: Invalid options.
*/
extern LZMA_API(lzma_ret) lzma_stream_header_encode(
const lzma_stream_flags *options, uint8_t *out)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Encode Stream Footer
*
* \param options Stream Footer options to be encoded.
* \param out Beginning of the output buffer of
* LZMA_STREAM_HEADER_SIZE bytes.
*
* \return - LZMA_OK: Encoding was successful.
* - LZMA_OPTIONS_ERROR: options->version is not supported by
* this liblzma version.
* - LZMA_PROG_ERROR: Invalid options.
*/
extern LZMA_API(lzma_ret) lzma_stream_footer_encode(
const lzma_stream_flags *options, uint8_t *out)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Decode Stream Header
*
* \param options Target for the decoded Stream Header options.
* \param in Beginning of the input buffer of
* LZMA_STREAM_HEADER_SIZE bytes.
*
* options->backward_size is always set to LZMA_VLI_UNKNOWN. This is to
* help comparing Stream Flags from Stream Header and Stream Footer with
* lzma_stream_flags_compare().
*
* \return - LZMA_OK: Decoding was successful.
* - LZMA_FORMAT_ERROR: Magic bytes don't match, thus the given
* buffer cannot be Stream Header.
* - LZMA_DATA_ERROR: CRC32 doesn't match, thus the header
* is corrupt.
* - LZMA_OPTIONS_ERROR: Unsupported options are present
* in the header.
*
* \note When decoding .xz files that contain multiple Streams, it may
* make sense to print "file format not recognized" only if
* decoding of the Stream Header of the _first_ Stream gives
* LZMA_FORMAT_ERROR. If non-first Stream Header gives
* LZMA_FORMAT_ERROR, the message used for LZMA_DATA_ERROR is
* probably more appropriate.
*
* For example, Stream decoder in liblzma uses LZMA_DATA_ERROR if
* LZMA_FORMAT_ERROR is returned by lzma_stream_header_decode()
* when decoding non-first Stream.
*/
extern LZMA_API(lzma_ret) lzma_stream_header_decode(
lzma_stream_flags *options, const uint8_t *in)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Decode Stream Footer
*
* \param options Target for the decoded Stream Header options.
* \param in Beginning of the input buffer of
* LZMA_STREAM_HEADER_SIZE bytes.
*
* \return - LZMA_OK: Decoding was successful.
* - LZMA_FORMAT_ERROR: Magic bytes don't match, thus the given
* buffer cannot be Stream Footer.
* - LZMA_DATA_ERROR: CRC32 doesn't match, thus the Stream Footer
* is corrupt.
* - LZMA_OPTIONS_ERROR: Unsupported options are present
* in Stream Footer.
*
* \note If Stream Header was already decoded successfully, but
* decoding Stream Footer returns LZMA_FORMAT_ERROR, the
* application should probably report some other error message
* than "file format not recognized", since the file more likely
* is corrupt (possibly truncated). Stream decoder in liblzma
* uses LZMA_DATA_ERROR in this situation.
*/
extern LZMA_API(lzma_ret) lzma_stream_footer_decode(
lzma_stream_flags *options, const uint8_t *in)
lzma_nothrow lzma_attr_warn_unused_result;
/**
* \brief Compare two lzma_stream_flags structures
*
* backward_size values are compared only if both are not
* LZMA_VLI_UNKNOWN.
*
* \return - LZMA_OK: Both are equal. If either had backward_size set
* to LZMA_VLI_UNKNOWN, backward_size values were not
* compared or validated.
* - LZMA_DATA_ERROR: The structures differ.
* - LZMA_OPTIONS_ERROR: version in either structure is greater
* than the maximum supported version (currently zero).
* - LZMA_PROG_ERROR: Invalid value, e.g. invalid check or
* backward_size.
*/
extern LZMA_API(lzma_ret) lzma_stream_flags_compare(
const lzma_stream_flags *a, const lzma_stream_flags *b)
lzma_nothrow lzma_attr_pure;

View File

@@ -1,126 +0,0 @@
/**
* \file lzma/version.h
* \brief Version number
*/
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/*
* Version number split into components
*/
#define LZMA_VERSION_MAJOR 5
#define LZMA_VERSION_MINOR 0
#define LZMA_VERSION_PATCH 3
#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_STABLE
#ifndef LZMA_VERSION_COMMIT
# define LZMA_VERSION_COMMIT ""
#endif
/*
* Map symbolic stability levels to integers.
*/
#define LZMA_VERSION_STABILITY_ALPHA 0
#define LZMA_VERSION_STABILITY_BETA 1
#define LZMA_VERSION_STABILITY_STABLE 2
/**
* \brief Compile-time version number
*
* The version number is of format xyyyzzzs where
* - x = major
* - yyy = minor
* - zzz = revision
* - s indicates stability: 0 = alpha, 1 = beta, 2 = stable
*
* The same xyyyzzz triplet is never reused with different stability levels.
* For example, if 5.1.0alpha has been released, there will never be 5.1.0beta
* or 5.1.0 stable.
*
* \note The version number of liblzma has nothing to with
* the version number of Igor Pavlov's LZMA SDK.
*/
#define LZMA_VERSION (LZMA_VERSION_MAJOR * UINT32_C(10000000) \
+ LZMA_VERSION_MINOR * UINT32_C(10000) \
+ LZMA_VERSION_PATCH * UINT32_C(10) \
+ LZMA_VERSION_STABILITY)
/*
* Macros to construct the compile-time version string
*/
#if LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_ALPHA
# define LZMA_VERSION_STABILITY_STRING "alpha"
#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_BETA
# define LZMA_VERSION_STABILITY_STRING "beta"
#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_STABLE
# define LZMA_VERSION_STABILITY_STRING ""
#else
# error Incorrect LZMA_VERSION_STABILITY
#endif
#define LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit) \
#major "." #minor "." #patch stability commit
#define LZMA_VERSION_STRING_C(major, minor, patch, stability, commit) \
LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit)
/**
* \brief Compile-time version as a string
*
* This can be for example "4.999.5alpha", "4.999.8beta", or "5.0.0" (stable
* versions don't have any "stable" suffix). In future, a snapshot built
* from source code repository may include an additional suffix, for example
* "4.999.8beta-21-g1d92". The commit ID won't be available in numeric form
* in LZMA_VERSION macro.
*/
#define LZMA_VERSION_STRING LZMA_VERSION_STRING_C( \
LZMA_VERSION_MAJOR, LZMA_VERSION_MINOR, \
LZMA_VERSION_PATCH, LZMA_VERSION_STABILITY_STRING, \
LZMA_VERSION_COMMIT)
/* #ifndef is needed for use with windres (MinGW or Cygwin). */
#ifndef LZMA_H_INTERNAL_RC
/**
* \brief Run-time version number as an integer
*
* Return the value of LZMA_VERSION macro at the compile time of liblzma.
* This allows the application to compare if it was built against the same,
* older, or newer version of liblzma that is currently running.
*/
extern LZMA_API(uint32_t) lzma_version_number(void)
lzma_nothrow lzma_attr_const;
/**
* \brief Run-time version as a string
*
* This function may be useful if you want to display which version of
* liblzma your application is currently using.
*/
extern LZMA_API(const char *) lzma_version_string(void)
lzma_nothrow lzma_attr_const;
#endif

View File

@@ -1,171 +0,0 @@
/**
* \file lzma/vli.h
* \brief Variable-length integer handling
*
* In the .xz format, most integers are encoded in a variable-length
* representation, which is sometimes called little endian base-128 encoding.
* This saves space when smaller values are more likely than bigger values.
*
* The encoding scheme encodes seven bits to every byte, using minimum
* number of bytes required to represent the given value. Encodings that use
* non-minimum number of bytes are invalid, thus every integer has exactly
* one encoded representation. The maximum number of bits in a VLI is 63,
* thus the vli argument must be less than or equal to UINT64_MAX / 2. You
* should use LZMA_VLI_MAX for clarity.
*/
/*
//
// Copyright 2012 Lasse Collin and Igor Pavlov
// Public Domain
//
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Maximum supported value of a variable-length integer
*/
#define LZMA_VLI_MAX (UINT64_MAX / 2)
/**
* \brief VLI value to denote that the value is unknown
*/
#define LZMA_VLI_UNKNOWN UINT64_MAX
/**
* \brief Maximum supported encoded length of variable length integers
*/
#define LZMA_VLI_BYTES_MAX 9
/**
* \brief VLI constant suffix
*/
#define LZMA_VLI_C(n) UINT64_C(n)
/**
* \brief Variable-length integer type
*
* Valid VLI values are in the range [0, LZMA_VLI_MAX]. Unknown value is
* indicated with LZMA_VLI_UNKNOWN, which is the maximum value of the
* underlaying integer type.
*
* lzma_vli will be uint64_t for the foreseeable future. If a bigger size
* is needed in the future, it is guaranteed that 2 * LZMA_VLI_MAX will
* not overflow lzma_vli. This simplifies integer overflow detection.
*/
typedef uint64_t lzma_vli;
/**
* \brief Validate a variable-length integer
*
* This is useful to test that application has given acceptable values
* for example in the uncompressed_size and compressed_size variables.
*
* \return True if the integer is representable as VLI or if it
* indicates unknown value.
*/
#define lzma_vli_is_valid(vli) \
((vli) <= LZMA_VLI_MAX || (vli) == LZMA_VLI_UNKNOWN)
/**
* \brief Encode a variable-length integer
*
* This function has two modes: single-call and multi-call. Single-call mode
* encodes the whole integer at once; it is an error if the output buffer is
* too small. Multi-call mode saves the position in *vli_pos, and thus it is
* possible to continue encoding if the buffer becomes full before the whole
* integer has been encoded.
*
* \param vli Integer to be encoded
* \param vli_pos How many VLI-encoded bytes have already been written
* out. When starting to encode a new integer in
* multi-call mode, *vli_pos must be set to zero.
* To use single-call encoding, set vli_pos to NULL.
* \param out Beginning of the output buffer
* \param out_pos The next byte will be written to out[*out_pos].
* \param out_size Size of the out buffer; the first byte into
* which no data is written to is out[out_size].
*
* \return Slightly different return values are used in multi-call and
* single-call modes.
*
* Single-call (vli_pos == NULL):
* - LZMA_OK: Integer successfully encoded.
* - LZMA_PROG_ERROR: Arguments are not sane. This can be due
* to too little output space; single-call mode doesn't use
* LZMA_BUF_ERROR, since the application should have checked
* the encoded size with lzma_vli_size().
*
* Multi-call (vli_pos != NULL):
* - LZMA_OK: So far all OK, but the integer is not
* completely written out yet.
* - LZMA_STREAM_END: Integer successfully encoded.
* - LZMA_BUF_ERROR: No output space was provided.
* - LZMA_PROG_ERROR: Arguments are not sane.
*/
extern LZMA_API(lzma_ret) lzma_vli_encode(lzma_vli vli, size_t *vli_pos,
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
/**
* \brief Decode a variable-length integer
*
* Like lzma_vli_encode(), this function has single-call and multi-call modes.
*
* \param vli Pointer to decoded integer. The decoder will
* initialize it to zero when *vli_pos == 0, so
* application isn't required to initialize *vli.
* \param vli_pos How many bytes have already been decoded. When
* starting to decode a new integer in multi-call
* mode, *vli_pos must be initialized to zero. To
* use single-call decoding, set vli_pos to NULL.
* \param in Beginning of the input buffer
* \param in_pos The next byte will be read from in[*in_pos].
* \param in_size Size of the input buffer; the first byte that
* won't be read is in[in_size].
*
* \return Slightly different return values are used in multi-call and
* single-call modes.
*
* Single-call (vli_pos == NULL):
* - LZMA_OK: Integer successfully decoded.
* - LZMA_DATA_ERROR: Integer is corrupt. This includes hitting
* the end of the input buffer before the whole integer was
* decoded; providing no input at all will use LZMA_DATA_ERROR.
* - LZMA_PROG_ERROR: Arguments are not sane.
*
* Multi-call (vli_pos != NULL):
* - LZMA_OK: So far all OK, but the integer is not
* completely decoded yet.
* - LZMA_STREAM_END: Integer successfully decoded.
* - LZMA_DATA_ERROR: Integer is corrupt.
* - LZMA_BUF_ERROR: No input was provided.
* - LZMA_PROG_ERROR: Arguments are not sane.
*/
extern LZMA_API(lzma_ret) lzma_vli_decode(lzma_vli *vli, size_t *vli_pos,
const uint8_t *in, size_t *in_pos, size_t in_size)
lzma_nothrow;
/**
* \brief Get the number of bytes required to encode a VLI
*
* \return Number of bytes on success (1-9). If vli isn't valid,
* zero is returned.
*/
extern LZMA_API(uint32_t) lzma_vli_size(lzma_vli vli)
lzma_nothrow lzma_attr_pure;

View File

@@ -1,190 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file check.c
/// \brief Single API to access different integrity checks
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "check.h"
#if __MOJOSETUP__ // use our crc32 to keep size down.
void MojoCrc32_append(uint32_t *_crc, const uint8_t *buf, uint32_t len);
extern LZMA_API(uint32_t)
lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc)
{
crc ^= 0xFFFFFFFF;
MojoCrc32_append(&crc, buf, (uint32_t) size);
return crc ^ 0xFFFFFFFF;
}
#endif
extern LZMA_API(lzma_bool)
lzma_check_is_supported(lzma_check type)
{
if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)
return false;
static const lzma_bool available_checks[LZMA_CHECK_ID_MAX + 1] = {
true, // LZMA_CHECK_NONE
#ifdef HAVE_CHECK_CRC32
true,
#else
false,
#endif
false, // Reserved
false, // Reserved
#ifdef HAVE_CHECK_CRC64
true,
#else
false,
#endif
false, // Reserved
false, // Reserved
false, // Reserved
false, // Reserved
false, // Reserved
#ifdef HAVE_CHECK_SHA256
true,
#else
false,
#endif
false, // Reserved
false, // Reserved
false, // Reserved
false, // Reserved
false, // Reserved
};
return available_checks[(unsigned int)(type)];
}
extern LZMA_API(uint32_t)
lzma_check_size(lzma_check type)
{
if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)
return UINT32_MAX;
// See file-format.txt section 2.1.1.2.
static const uint8_t check_sizes[LZMA_CHECK_ID_MAX + 1] = {
0,
4, 4, 4,
8, 8, 8,
16, 16, 16,
32, 32, 32,
64, 64, 64
};
return check_sizes[(unsigned int)(type)];
}
extern void
lzma_check_init(lzma_check_state *check, lzma_check type)
{
switch (type) {
case LZMA_CHECK_NONE:
break;
#ifdef HAVE_CHECK_CRC32
case LZMA_CHECK_CRC32:
check->state.crc32 = 0;
break;
#endif
#ifdef HAVE_CHECK_CRC64
case LZMA_CHECK_CRC64:
check->state.crc64 = 0;
break;
#endif
#ifdef HAVE_CHECK_SHA256
case LZMA_CHECK_SHA256:
lzma_sha256_init(check);
break;
#endif
default:
break;
}
return;
}
extern void
lzma_check_update(lzma_check_state *check, lzma_check type,
const uint8_t *buf, size_t size)
{
switch (type) {
#ifdef HAVE_CHECK_CRC32
case LZMA_CHECK_CRC32:
check->state.crc32 = lzma_crc32(buf, size, check->state.crc32);
break;
#endif
#ifdef HAVE_CHECK_CRC64
case LZMA_CHECK_CRC64:
check->state.crc64 = lzma_crc64(buf, size, check->state.crc64);
break;
#endif
#ifdef HAVE_CHECK_SHA256
case LZMA_CHECK_SHA256:
lzma_sha256_update(buf, size, check);
break;
#endif
default:
break;
}
return;
}
extern void
lzma_check_finish(lzma_check_state *check, lzma_check type)
{
switch (type) {
#ifdef HAVE_CHECK_CRC32
case LZMA_CHECK_CRC32:
check->buffer.u32[0] = conv32le(check->state.crc32);
break;
#endif
#ifdef HAVE_CHECK_CRC64
case LZMA_CHECK_CRC64:
check->buffer.u64[0] = conv64le(check->state.crc64);
break;
#endif
#ifdef HAVE_CHECK_SHA256
case LZMA_CHECK_SHA256:
lzma_sha256_finish(check);
break;
#endif
default:
break;
}
return;
}

View File

@@ -1,103 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file check.h
/// \brief Internal API to different integrity check functions
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_CHECK_H
#define LZMA_CHECK_H
#include "common.h"
#if __MOJOSETUP__
#define HAVE_CHECK_CRC32 1
#endif
// Index hashing needs the best possible hash function (preferably
// a cryptographic hash) for maximum reliability.
#if defined(HAVE_CHECK_SHA256)
# define LZMA_CHECK_BEST LZMA_CHECK_SHA256
#elif defined(HAVE_CHECK_CRC64)
# define LZMA_CHECK_BEST LZMA_CHECK_CRC64
#else
# define LZMA_CHECK_BEST LZMA_CHECK_CRC32
#endif
/// \brief Structure to hold internal state of the check being calculated
///
/// \note This is not in the public API because this structure may
/// change in future if new integrity check algorithms are added.
typedef struct {
/// Buffer to hold the final result and a temporary buffer for SHA256.
union {
uint8_t u8[64];
uint32_t u32[16];
uint64_t u64[8];
} buffer;
/// Check-specific data
union {
uint32_t crc32;
uint64_t crc64;
struct {
/// Internal state
uint32_t state[8];
/// Size of the message excluding padding
uint64_t size;
} sha256;
} state;
} lzma_check_state;
/// lzma_crc32_table[0] is needed by LZ encoder so we need to keep
/// the array two-dimensional.
#ifdef HAVE_SMALL
extern uint32_t lzma_crc32_table[1][256];
extern void lzma_crc32_init(void);
#else
extern const uint32_t lzma_crc32_table[8][256];
extern const uint64_t lzma_crc64_table[4][256];
#endif
/// \brief Initialize *check depending on type
///
/// \return LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not
/// supported by the current version or build of liblzma.
/// LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX.
extern void lzma_check_init(lzma_check_state *check, lzma_check type);
/// Update the check state
extern void lzma_check_update(lzma_check_state *check, lzma_check type,
const uint8_t *buf, size_t size);
/// Finish the check calculation and store the result to check->buffer.u8.
extern void lzma_check_finish(lzma_check_state *check, lzma_check type);
/// Prepare SHA-256 state for new input.
extern void lzma_sha256_init(lzma_check_state *check);
/// Update the SHA-256 hash state
extern void lzma_sha256_update(
const uint8_t *buf, size_t size, lzma_check_state *check);
/// Finish the SHA-256 calculation and store the result to check->buffer.u8.
extern void lzma_sha256_finish(lzma_check_state *check);
#endif

View File

@@ -1,35 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file crc_macros.h
/// \brief Some endian-dependent macros for CRC32 and CRC64
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifdef WORDS_BIGENDIAN
# define A(x) ((x) >> 24)
# define B(x) (((x) >> 16) & 0xFF)
# define C(x) (((x) >> 8) & 0xFF)
# define D(x) ((x) & 0xFF)
# define S8(x) ((x) << 8)
# define S32(x) ((x) << 32)
#else
# define A(x) ((x) & 0xFF)
# define B(x) (((x) >> 8) & 0xFF)
# define C(x) (((x) >> 16) & 0xFF)
# define D(x) ((x) >> 24)
# define S8(x) ((x) >> 8)
# define S32(x) ((x) >> 32)
#endif

View File

@@ -1,237 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file alone_decoder.c
/// \brief Decoder for LZMA_Alone files
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "alone_decoder.h"
#include "lzma_decoder.h"
#include "lz_decoder.h"
struct lzma_coder_s {
lzma_next_coder next;
enum {
SEQ_PROPERTIES,
SEQ_DICTIONARY_SIZE,
SEQ_UNCOMPRESSED_SIZE,
SEQ_CODER_INIT,
SEQ_CODE,
} sequence;
/// Position in the header fields
size_t pos;
/// Uncompressed size decoded from the header
lzma_vli uncompressed_size;
/// Memory usage limit
uint64_t memlimit;
/// Amount of memory actually needed (only an estimate)
uint64_t memusage;
/// Options decoded from the header needed to initialize
/// the LZMA decoder
lzma_options_lzma options;
};
static lzma_ret
alone_decode(lzma_coder *coder,
lzma_allocator *allocator lzma_attribute((__unused__)),
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size,
lzma_action action)
{
while (*out_pos < out_size
&& (coder->sequence == SEQ_CODE || *in_pos < in_size))
switch (coder->sequence) {
case SEQ_PROPERTIES:
if (lzma_lzma_lclppb_decode(&coder->options, in[*in_pos]))
return LZMA_FORMAT_ERROR;
coder->sequence = SEQ_DICTIONARY_SIZE;
++*in_pos;
break;
case SEQ_DICTIONARY_SIZE:
coder->options.dict_size
|= (size_t)(in[*in_pos]) << (coder->pos * 8);
if (++coder->pos == 4) {
if (coder->options.dict_size != UINT32_MAX) {
// A hack to ditch tons of false positives:
// We allow only dictionary sizes that are
// 2^n or 2^n + 2^(n-1). LZMA_Alone created
// only files with 2^n, but accepts any
// dictionary size. If someone complains, this
// will be reconsidered.
uint32_t d = coder->options.dict_size - 1;
d |= d >> 2;
d |= d >> 3;
d |= d >> 4;
d |= d >> 8;
d |= d >> 16;
++d;
if (d != coder->options.dict_size)
return LZMA_FORMAT_ERROR;
}
coder->pos = 0;
coder->sequence = SEQ_UNCOMPRESSED_SIZE;
}
++*in_pos;
break;
case SEQ_UNCOMPRESSED_SIZE:
coder->uncompressed_size
|= (lzma_vli)(in[*in_pos]) << (coder->pos * 8);
++*in_pos;
if (++coder->pos < 8)
break;
// Another hack to ditch false positives: Assume that
// if the uncompressed size is known, it must be less
// than 256 GiB. Again, if someone complains, this
// will be reconsidered.
if (coder->uncompressed_size != LZMA_VLI_UNKNOWN
&& coder->uncompressed_size
>= (LZMA_VLI_C(1) << 38))
return LZMA_FORMAT_ERROR;
// Calculate the memory usage so that it is ready
// for SEQ_CODER_INIT.
coder->memusage = lzma_lzma_decoder_memusage(&coder->options)
+ LZMA_MEMUSAGE_BASE;
coder->pos = 0;
coder->sequence = SEQ_CODER_INIT;
// Fall through
case SEQ_CODER_INIT: {
if (coder->memusage > coder->memlimit)
return LZMA_MEMLIMIT_ERROR;
lzma_filter_info filters[2] = {
{
.init = &lzma_lzma_decoder_init,
.options = &coder->options,
}, {
.init = NULL,
}
};
const lzma_ret ret = lzma_next_filter_init(&coder->next,
allocator, filters);
if (ret != LZMA_OK)
return ret;
// Use a hack to set the uncompressed size.
lzma_lz_decoder_uncompressed(coder->next.coder,
coder->uncompressed_size);
coder->sequence = SEQ_CODE;
break;
}
case SEQ_CODE: {
return coder->next.code(coder->next.coder,
allocator, in, in_pos, in_size,
out, out_pos, out_size, action);
}
default:
return LZMA_PROG_ERROR;
}
return LZMA_OK;
}
static void
alone_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
{
lzma_next_end(&coder->next, allocator);
lzma_free(coder, allocator);
return;
}
static lzma_ret
alone_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
uint64_t *old_memlimit, uint64_t new_memlimit)
{
*memusage = coder->memusage;
*old_memlimit = coder->memlimit;
if (new_memlimit != 0) {
if (new_memlimit < coder->memusage)
return LZMA_MEMLIMIT_ERROR;
coder->memlimit = new_memlimit;
}
return LZMA_OK;
}
extern lzma_ret
lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
uint64_t memlimit)
{
lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator);
if (memlimit == 0)
return LZMA_PROG_ERROR;
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
return LZMA_MEM_ERROR;
next->code = &alone_decode;
next->end = &alone_decoder_end;
next->memconfig = &alone_decoder_memconfig;
next->coder->next = LZMA_NEXT_CODER_INIT;
}
next->coder->sequence = SEQ_PROPERTIES;
next->coder->pos = 0;
next->coder->options.dict_size = 0;
next->coder->options.preset_dict = NULL;
next->coder->options.preset_dict_size = 0;
next->coder->uncompressed_size = 0;
next->coder->memlimit = memlimit;
next->coder->memusage = LZMA_MEMUSAGE_BASE;
return LZMA_OK;
}
extern LZMA_API(lzma_ret)
lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit)
{
lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit);
strm->internal->supported_actions[LZMA_RUN] = true;
strm->internal->supported_actions[LZMA_FINISH] = true;
return LZMA_OK;
}

View File

@@ -1,27 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file alone_decoder.h
/// \brief Decoder for LZMA_Alone files
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_ALONE_DECODER_H
#define LZMA_ALONE_DECODER_H
#include "common.h"
extern lzma_ret lzma_alone_decoder_init(lzma_next_coder *next,
lzma_allocator *allocator, uint64_t memlimit);
#endif

View File

@@ -1,83 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file block_buffer_decoder.c
/// \brief Single-call .xz Block decoder
//
// Copyright 2012 Lasse Collin
// Public Domain
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "block_decoder.h"
extern LZMA_API(lzma_ret)
lzma_block_buffer_decode(lzma_block *block, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos, size_t in_size,
uint8_t *out, size_t *out_pos, size_t out_size)
{
if (in_pos == NULL || (in == NULL && *in_pos != in_size)
|| *in_pos > in_size || out_pos == NULL
|| (out == NULL && *out_pos != out_size)
|| *out_pos > out_size)
return LZMA_PROG_ERROR;
// Initialize the Block decoder.
lzma_next_coder block_decoder = LZMA_NEXT_CODER_INIT;
lzma_ret ret = lzma_block_decoder_init(
&block_decoder, allocator, block);
if (ret == LZMA_OK) {
// Save the positions so that we can restore them in case
// an error occurs.
const size_t in_start = *in_pos;
const size_t out_start = *out_pos;
// Do the actual decoding.
ret = block_decoder.code(block_decoder.coder, allocator,
in, in_pos, in_size, out, out_pos, out_size,
LZMA_FINISH);
if (ret == LZMA_STREAM_END) {
ret = LZMA_OK;
} else {
if (ret == LZMA_OK) {
// Either the input was truncated or the
// output buffer was too small.
assert(*in_pos == in_size
|| *out_pos == out_size);
// If all the input was consumed, then the
// input is truncated, even if the output
// buffer is also full. This is because
// processing the last byte of the Block
// never produces output.
//
// NOTE: This assumption may break when new
// filters are added, if the end marker of
// the filter doesn't consume at least one
// complete byte.
if (*in_pos == in_size)
ret = LZMA_DATA_ERROR;
else
ret = LZMA_BUF_ERROR;
}
// Restore the positions.
*in_pos = in_start;
*out_pos = out_start;
}
}
// Free the decoder memory. This needs to be done even if
// initialization fails, because the internal API doesn't
// require the initialization function to free its memory on error.
lzma_next_end(&block_decoder, allocator);
return ret;
}

View File

@@ -1,247 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file block_decoder.c
/// \brief Decodes .xz Blocks
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "block_decoder.h"
#include "filter_decoder.h"
#include "check.h"
struct lzma_coder_s {
enum {
SEQ_CODE,
SEQ_PADDING,
SEQ_CHECK,
} sequence;
/// The filters in the chain; initialized with lzma_raw_decoder_init().
lzma_next_coder next;
/// Decoding options; we also write Compressed Size and Uncompressed
/// Size back to this structure when the decoding has been finished.
lzma_block *block;
/// Compressed Size calculated while decoding
lzma_vli compressed_size;
/// Uncompressed Size calculated while decoding
lzma_vli uncompressed_size;
/// Maximum allowed Compressed Size; this takes into account the
/// size of the Block Header and Check fields when Compressed Size
/// is unknown.
lzma_vli compressed_limit;
/// Position when reading the Check field
size_t check_pos;
/// Check of the uncompressed data
lzma_check_state check;
};
static inline bool
update_size(lzma_vli *size, lzma_vli add, lzma_vli limit)
{
if (limit > LZMA_VLI_MAX)
limit = LZMA_VLI_MAX;
if (limit < *size || limit - *size < add)
return true;
*size += add;
return false;
}
static inline bool
is_size_valid(lzma_vli size, lzma_vli reference)
{
return reference == LZMA_VLI_UNKNOWN || reference == size;
}
static lzma_ret
block_decode(lzma_coder *coder, lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
switch (coder->sequence) {
case SEQ_CODE: {
const size_t in_start = *in_pos;
const size_t out_start = *out_pos;
const lzma_ret ret = coder->next.code(coder->next.coder,
allocator, in, in_pos, in_size,
out, out_pos, out_size, action);
const size_t in_used = *in_pos - in_start;
const size_t out_used = *out_pos - out_start;
// NOTE: We compare to compressed_limit here, which prevents
// the total size of the Block growing past LZMA_VLI_MAX.
if (update_size(&coder->compressed_size, in_used,
coder->compressed_limit)
|| update_size(&coder->uncompressed_size,
out_used,
coder->block->uncompressed_size))
return LZMA_DATA_ERROR;
lzma_check_update(&coder->check, coder->block->check,
out + out_start, out_used);
if (ret != LZMA_STREAM_END)
return ret;
// Compressed and Uncompressed Sizes are now at their final
// values. Verify that they match the values given to us.
if (!is_size_valid(coder->compressed_size,
coder->block->compressed_size)
|| !is_size_valid(coder->uncompressed_size,
coder->block->uncompressed_size))
return LZMA_DATA_ERROR;
// Copy the values into coder->block. The caller
// may use this information to construct Index.
coder->block->compressed_size = coder->compressed_size;
coder->block->uncompressed_size = coder->uncompressed_size;
coder->sequence = SEQ_PADDING;
}
// Fall through
case SEQ_PADDING:
// Compressed Data is padded to a multiple of four bytes.
while (coder->compressed_size & 3) {
if (*in_pos >= in_size)
return LZMA_OK;
// We use compressed_size here just get the Padding
// right. The actual Compressed Size was stored to
// coder->block already, and won't be modified by
// us anymore.
++coder->compressed_size;
if (in[(*in_pos)++] != 0x00)
return LZMA_DATA_ERROR;
}
if (coder->block->check == LZMA_CHECK_NONE)
return LZMA_STREAM_END;
lzma_check_finish(&coder->check, coder->block->check);
coder->sequence = SEQ_CHECK;
// Fall through
case SEQ_CHECK: {
const size_t check_size = lzma_check_size(coder->block->check);
lzma_bufcpy(in, in_pos, in_size, coder->block->raw_check,
&coder->check_pos, check_size);
if (coder->check_pos < check_size)
return LZMA_OK;
// Validate the Check only if we support it.
// coder->check.buffer may be uninitialized
// when the Check ID is not supported.
if (lzma_check_is_supported(coder->block->check)
&& memcmp(coder->block->raw_check,
coder->check.buffer.u8,
check_size) != 0)
return LZMA_DATA_ERROR;
return LZMA_STREAM_END;
}
}
return LZMA_PROG_ERROR;
}
static void
block_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
{
lzma_next_end(&coder->next, allocator);
lzma_free(coder, allocator);
return;
}
extern lzma_ret
lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
lzma_block *block)
{
lzma_next_coder_init(&lzma_block_decoder_init, next, allocator);
// Validate the options. lzma_block_unpadded_size() does that for us
// except for Uncompressed Size and filters. Filters are validated
// by the raw decoder.
if (lzma_block_unpadded_size(block) == 0
|| !lzma_vli_is_valid(block->uncompressed_size))
return LZMA_PROG_ERROR;
// Allocate and initialize *next->coder if needed.
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
return LZMA_MEM_ERROR;
next->code = &block_decode;
next->end = &block_decoder_end;
next->coder->next = LZMA_NEXT_CODER_INIT;
}
// Basic initializations
next->coder->sequence = SEQ_CODE;
next->coder->block = block;
next->coder->compressed_size = 0;
next->coder->uncompressed_size = 0;
// If Compressed Size is not known, we calculate the maximum allowed
// value so that encoded size of the Block (including Block Padding)
// is still a valid VLI and a multiple of four.
next->coder->compressed_limit
= block->compressed_size == LZMA_VLI_UNKNOWN
? (LZMA_VLI_MAX & ~LZMA_VLI_C(3))
- block->header_size
- lzma_check_size(block->check)
: block->compressed_size;
// Initialize the check. It's caller's problem if the Check ID is not
// supported, and the Block decoder cannot verify the Check field.
// Caller can test lzma_check_is_supported(block->check).
next->coder->check_pos = 0;
lzma_check_init(&next->coder->check, block->check);
// Initialize the filter chain.
return lzma_raw_decoder_init(&next->coder->next, allocator,
block->filters);
}
extern LZMA_API(lzma_ret)
lzma_block_decoder(lzma_stream *strm, lzma_block *block)
{
lzma_next_strm_init(lzma_block_decoder_init, strm, block);
strm->internal->supported_actions[LZMA_RUN] = true;
strm->internal->supported_actions[LZMA_FINISH] = true;
return LZMA_OK;
}

View File

@@ -1,27 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file block_decoder.h
/// \brief Decodes .xz Blocks
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_BLOCK_DECODER_H
#define LZMA_BLOCK_DECODER_H
#include "common.h"
extern lzma_ret lzma_block_decoder_init(lzma_next_coder *next,
lzma_allocator *allocator, lzma_block *block);
#endif

View File

@@ -1,135 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file block_header_decoder.c
/// \brief Decodes Block Header from .xz files
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "common.h"
#include "check.h"
static void
free_properties(lzma_block *block, lzma_allocator *allocator)
{
// Free allocated filter options. The last array member is not
// touched after the initialization in the beginning of
// lzma_block_header_decode(), so we don't need to touch that here.
#if __MOJOSETUP__
size_t i;
for (i = 0; i < LZMA_FILTERS_MAX; ++i) {
#else
for (size_t i = 0; i < LZMA_FILTERS_MAX; ++i) {
#endif
lzma_free(block->filters[i].options, allocator);
block->filters[i].id = LZMA_VLI_UNKNOWN;
block->filters[i].options = NULL;
}
return;
}
extern LZMA_API(lzma_ret)
lzma_block_header_decode(lzma_block *block,
lzma_allocator *allocator, const uint8_t *in)
{
// NOTE: We consider the header to be corrupt not only when the
// CRC32 doesn't match, but also when variable-length integers
// are invalid or over 63 bits, or if the header is too small
// to contain the claimed information.
// Initialize the filter options array. This way the caller can
// safely free() the options even if an error occurs in this function.
#if __MOJOSETUP__
size_t i;
for (i = 0; i <= LZMA_FILTERS_MAX; ++i) {
#else
for (size_t i = 0; i <= LZMA_FILTERS_MAX; ++i) {
#endif
block->filters[i].id = LZMA_VLI_UNKNOWN;
block->filters[i].options = NULL;
}
// Always zero for now.
block->version = 0;
// Validate Block Header Size and Check type. The caller must have
// already set these, so it is a programming error if this test fails.
if (lzma_block_header_size_decode(in[0]) != block->header_size
|| (unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
return LZMA_PROG_ERROR;
// Exclude the CRC32 field.
const size_t in_size = block->header_size - 4;
// Verify CRC32
if (lzma_crc32(in, in_size, 0) != unaligned_read32le(in + in_size))
return LZMA_DATA_ERROR;
// Check for unsupported flags.
if (in[1] & 0x3C)
return LZMA_OPTIONS_ERROR;
// Start after the Block Header Size and Block Flags fields.
size_t in_pos = 2;
// Compressed Size
if (in[1] & 0x40) {
return_if_error(lzma_vli_decode(&block->compressed_size,
NULL, in, &in_pos, in_size));
// Validate Compressed Size. This checks that it isn't zero
// and that the total size of the Block is a valid VLI.
if (lzma_block_unpadded_size(block) == 0)
return LZMA_DATA_ERROR;
} else {
block->compressed_size = LZMA_VLI_UNKNOWN;
}
// Uncompressed Size
if (in[1] & 0x80)
return_if_error(lzma_vli_decode(&block->uncompressed_size,
NULL, in, &in_pos, in_size));
else
block->uncompressed_size = LZMA_VLI_UNKNOWN;
// Filter Flags
const size_t filter_count = (in[1] & 3) + 1;
#if __MOJOSETUP__
for (i = 0; i < filter_count; ++i) {
#else
for (size_t i = 0; i < filter_count; ++i) {
#endif
const lzma_ret ret = lzma_filter_flags_decode(
&block->filters[i], allocator,
in, &in_pos, in_size);
if (ret != LZMA_OK) {
free_properties(block, allocator);
return ret;
}
}
// Padding
while (in_pos < in_size) {
if (in[in_pos++] != 0x00) {
free_properties(block, allocator);
// Possibly some new field present so use
// LZMA_OPTIONS_ERROR instead of LZMA_DATA_ERROR.
return LZMA_OPTIONS_ERROR;
}
}
return LZMA_OK;
}

View File

@@ -1,95 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file block_header.c
/// \brief Utility functions to handle lzma_block
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "common.h"
#include "index.h"
extern LZMA_API(lzma_ret)
lzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size)
{
// Validate everything but Uncompressed Size and filters.
if (lzma_block_unpadded_size(block) == 0)
return LZMA_PROG_ERROR;
const uint32_t container_size = block->header_size
+ lzma_check_size(block->check);
// Validate that Compressed Size will be greater than zero.
if (unpadded_size <= container_size)
return LZMA_DATA_ERROR;
// Calculate what Compressed Size is supposed to be.
// If Compressed Size was present in Block Header,
// compare that the new value matches it.
const lzma_vli compressed_size = unpadded_size - container_size;
if (block->compressed_size != LZMA_VLI_UNKNOWN
&& block->compressed_size != compressed_size)
return LZMA_DATA_ERROR;
block->compressed_size = compressed_size;
return LZMA_OK;
}
extern LZMA_API(lzma_vli)
lzma_block_unpadded_size(const lzma_block *block)
{
// Validate the values that we are interested in i.e. all but
// Uncompressed Size and the filters.
//
// NOTE: This function is used for validation too, so it is
// essential that these checks are always done even if
// Compressed Size is unknown.
if (block == NULL || block->version != 0
|| block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN
|| block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX
|| (block->header_size & 3)
|| !lzma_vli_is_valid(block->compressed_size)
|| block->compressed_size == 0
|| (unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
return 0;
// If Compressed Size is unknown, return that we cannot know
// size of the Block either.
if (block->compressed_size == LZMA_VLI_UNKNOWN)
return LZMA_VLI_UNKNOWN;
// Calculate Unpadded Size and validate it.
const lzma_vli unpadded_size = block->compressed_size
+ block->header_size
+ lzma_check_size(block->check);
assert(unpadded_size >= UNPADDED_SIZE_MIN);
if (unpadded_size > UNPADDED_SIZE_MAX)
return 0;
return unpadded_size;
}
extern LZMA_API(lzma_vli)
lzma_block_total_size(const lzma_block *block)
{
lzma_vli unpadded_size = lzma_block_unpadded_size(block);
if (unpadded_size != LZMA_VLI_UNKNOWN)
unpadded_size = vli_ceil4(unpadded_size);
return unpadded_size;
}

View File

@@ -1,393 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file common.h
/// \brief Common functions needed in many places in liblzma
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "common.h"
/////////////
// Version //
/////////////
extern LZMA_API(uint32_t)
lzma_version_number(void)
{
return LZMA_VERSION;
}
extern LZMA_API(const char *)
lzma_version_string(void)
{
return LZMA_VERSION_STRING;
}
///////////////////////
// Memory allocation //
///////////////////////
extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
lzma_alloc(size_t size, lzma_allocator *allocator)
{
// Some malloc() variants return NULL if called with size == 0.
if (size == 0)
size = 1;
void *ptr;
if (allocator != NULL && allocator->alloc != NULL)
ptr = allocator->alloc(allocator->opaque, 1, size);
else
ptr = malloc(size);
return ptr;
}
extern void
lzma_free(void *ptr, lzma_allocator *allocator)
{
if (allocator != NULL && allocator->free != NULL)
allocator->free(allocator->opaque, ptr);
else
free(ptr);
return;
}
//////////
// Misc //
//////////
extern size_t
lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size)
{
const size_t in_avail = in_size - *in_pos;
const size_t out_avail = out_size - *out_pos;
const size_t copy_size = my_min(in_avail, out_avail);
memcpy(out + *out_pos, in + *in_pos, copy_size);
*in_pos += copy_size;
*out_pos += copy_size;
return copy_size;
}
extern lzma_ret
lzma_next_filter_init(lzma_next_coder *next, lzma_allocator *allocator,
const lzma_filter_info *filters)
{
lzma_next_coder_init(filters[0].init, next, allocator);
next->id = filters[0].id;
return filters[0].init == NULL
? LZMA_OK : filters[0].init(next, allocator, filters);
}
extern lzma_ret
lzma_next_filter_update(lzma_next_coder *next, lzma_allocator *allocator,
const lzma_filter *reversed_filters)
{
// Check that the application isn't trying to change the Filter ID.
// End of filters is indicated with LZMA_VLI_UNKNOWN in both
// reversed_filters[0].id and next->id.
if (reversed_filters[0].id != next->id)
return LZMA_PROG_ERROR;
if (reversed_filters[0].id == LZMA_VLI_UNKNOWN)
return LZMA_OK;
assert(next->update != NULL);
return next->update(next->coder, allocator, NULL, reversed_filters);
}
extern void
lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator)
{
if (next->init != (uintptr_t)(NULL)) {
// To avoid tiny end functions that simply call
// lzma_free(coder, allocator), we allow leaving next->end
// NULL and call lzma_free() here.
if (next->end != NULL)
next->end(next->coder, allocator);
else
lzma_free(next->coder, allocator);
// Reset the variables so the we don't accidentally think
// that it is an already initialized coder.
*next = LZMA_NEXT_CODER_INIT;
}
return;
}
//////////////////////////////////////
// External to internal API wrapper //
//////////////////////////////////////
extern lzma_ret
lzma_strm_init(lzma_stream *strm)
{
if (strm == NULL)
return LZMA_PROG_ERROR;
if (strm->internal == NULL) {
strm->internal = lzma_alloc(sizeof(lzma_internal),
strm->allocator);
if (strm->internal == NULL)
return LZMA_MEM_ERROR;
strm->internal->next = LZMA_NEXT_CODER_INIT;
}
strm->internal->supported_actions[LZMA_RUN] = false;
strm->internal->supported_actions[LZMA_SYNC_FLUSH] = false;
strm->internal->supported_actions[LZMA_FULL_FLUSH] = false;
strm->internal->supported_actions[LZMA_FINISH] = false;
strm->internal->sequence = ISEQ_RUN;
strm->internal->allow_buf_error = false;
strm->total_in = 0;
strm->total_out = 0;
return LZMA_OK;
}
extern LZMA_API(lzma_ret)
lzma_code(lzma_stream *strm, lzma_action action)
{
// Sanity checks
if ((strm->next_in == NULL && strm->avail_in != 0)
|| (strm->next_out == NULL && strm->avail_out != 0)
|| strm->internal == NULL
|| strm->internal->next.code == NULL
|| (unsigned int)(action) > LZMA_FINISH
|| !strm->internal->supported_actions[action])
return LZMA_PROG_ERROR;
// Check if unsupported members have been set to non-zero or non-NULL,
// which would indicate that some new feature is wanted.
if (strm->reserved_ptr1 != NULL
|| strm->reserved_ptr2 != NULL
|| strm->reserved_ptr3 != NULL
|| strm->reserved_ptr4 != NULL
|| strm->reserved_int1 != 0
|| strm->reserved_int2 != 0
|| strm->reserved_int3 != 0
|| strm->reserved_int4 != 0
|| strm->reserved_enum1 != LZMA_RESERVED_ENUM
|| strm->reserved_enum2 != LZMA_RESERVED_ENUM)
return LZMA_OPTIONS_ERROR;
switch (strm->internal->sequence) {
case ISEQ_RUN:
switch (action) {
case LZMA_RUN:
break;
case LZMA_SYNC_FLUSH:
strm->internal->sequence = ISEQ_SYNC_FLUSH;
break;
case LZMA_FULL_FLUSH:
strm->internal->sequence = ISEQ_FULL_FLUSH;
break;
case LZMA_FINISH:
strm->internal->sequence = ISEQ_FINISH;
break;
}
break;
case ISEQ_SYNC_FLUSH:
// The same action must be used until we return
// LZMA_STREAM_END, and the amount of input must not change.
if (action != LZMA_SYNC_FLUSH
|| strm->internal->avail_in != strm->avail_in)
return LZMA_PROG_ERROR;
break;
case ISEQ_FULL_FLUSH:
if (action != LZMA_FULL_FLUSH
|| strm->internal->avail_in != strm->avail_in)
return LZMA_PROG_ERROR;
break;
case ISEQ_FINISH:
if (action != LZMA_FINISH
|| strm->internal->avail_in != strm->avail_in)
return LZMA_PROG_ERROR;
break;
case ISEQ_END:
return LZMA_STREAM_END;
case ISEQ_ERROR:
default:
return LZMA_PROG_ERROR;
}
size_t in_pos = 0;
size_t out_pos = 0;
lzma_ret ret = strm->internal->next.code(
strm->internal->next.coder, strm->allocator,
strm->next_in, &in_pos, strm->avail_in,
strm->next_out, &out_pos, strm->avail_out, action);
strm->next_in += in_pos;
strm->avail_in -= in_pos;
strm->total_in += in_pos;
strm->next_out += out_pos;
strm->avail_out -= out_pos;
strm->total_out += out_pos;
strm->internal->avail_in = strm->avail_in;
switch (ret) {
case LZMA_OK:
// Don't return LZMA_BUF_ERROR when it happens the first time.
// This is to avoid returning LZMA_BUF_ERROR when avail_out
// was zero but still there was no more data left to written
// to next_out.
if (out_pos == 0 && in_pos == 0) {
if (strm->internal->allow_buf_error)
ret = LZMA_BUF_ERROR;
else
strm->internal->allow_buf_error = true;
} else {
strm->internal->allow_buf_error = false;
}
break;
case LZMA_STREAM_END:
if (strm->internal->sequence == ISEQ_SYNC_FLUSH
|| strm->internal->sequence == ISEQ_FULL_FLUSH)
strm->internal->sequence = ISEQ_RUN;
else
strm->internal->sequence = ISEQ_END;
// Fall through
case LZMA_NO_CHECK:
case LZMA_UNSUPPORTED_CHECK:
case LZMA_GET_CHECK:
case LZMA_MEMLIMIT_ERROR:
// Something else than LZMA_OK, but not a fatal error,
// that is, coding may be continued (except if ISEQ_END).
strm->internal->allow_buf_error = false;
break;
default:
// All the other errors are fatal; coding cannot be continued.
assert(ret != LZMA_BUF_ERROR);
strm->internal->sequence = ISEQ_ERROR;
break;
}
return ret;
}
extern LZMA_API(void)
lzma_end(lzma_stream *strm)
{
if (strm != NULL && strm->internal != NULL) {
lzma_next_end(&strm->internal->next, strm->allocator);
lzma_free(strm->internal, strm->allocator);
strm->internal = NULL;
}
return;
}
extern LZMA_API(lzma_check)
lzma_get_check(const lzma_stream *strm)
{
// Return LZMA_CHECK_NONE if we cannot know the check type.
// It's a bug in the application if this happens.
if (strm->internal->next.get_check == NULL)
return LZMA_CHECK_NONE;
return strm->internal->next.get_check(strm->internal->next.coder);
}
extern LZMA_API(uint64_t)
lzma_memusage(const lzma_stream *strm)
{
uint64_t memusage;
uint64_t old_memlimit;
if (strm == NULL || strm->internal == NULL
|| strm->internal->next.memconfig == NULL
|| strm->internal->next.memconfig(
strm->internal->next.coder,
&memusage, &old_memlimit, 0) != LZMA_OK)
return 0;
return memusage;
}
extern LZMA_API(uint64_t)
lzma_memlimit_get(const lzma_stream *strm)
{
uint64_t old_memlimit;
uint64_t memusage;
if (strm == NULL || strm->internal == NULL
|| strm->internal->next.memconfig == NULL
|| strm->internal->next.memconfig(
strm->internal->next.coder,
&memusage, &old_memlimit, 0) != LZMA_OK)
return 0;
return old_memlimit;
}
extern LZMA_API(lzma_ret)
lzma_memlimit_set(lzma_stream *strm, uint64_t new_memlimit)
{
// Dummy variables to simplify memconfig functions
uint64_t old_memlimit;
uint64_t memusage;
if (strm == NULL || strm->internal == NULL
|| strm->internal->next.memconfig == NULL)
return LZMA_PROG_ERROR;
if (new_memlimit != 0 && new_memlimit < LZMA_MEMUSAGE_BASE)
return LZMA_MEMLIMIT_ERROR;
return strm->internal->next.memconfig(strm->internal->next.coder,
&memusage, &old_memlimit, new_memlimit);
}

View File

@@ -1,301 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file common.h
/// \brief Definitions common to the whole liblzma library
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_COMMON_H
#define LZMA_COMMON_H
#if __MOJOSETUP__
#define HAVE_DECODER_LZMA1 1
#define HAVE_DECODER_LZMA2 1
#define HAVE_DECODER_X86 1
#define HAVE_DECODER_POWERPC 1
#define HAVE_DECODER_IA64 1
#define HAVE_DECODER_ARM 1
#define HAVE_DECODER_ARMTHUMB 1
#define HAVE_DECODER_SPARC 1
#define HAVE_DECODER_DELTA 1
#endif
#include "sysdefs.h"
#include "mythread.h"
#include "tuklib_integer.h"
#if defined(_WIN32) || defined(__CYGWIN__)
# ifdef DLL_EXPORT
# define LZMA_API_EXPORT __declspec(dllexport)
# else
# define LZMA_API_EXPORT
# endif
// Don't use ifdef or defined() below.
#elif HAVE_VISIBILITY
# define LZMA_API_EXPORT __attribute__((__visibility__("default")))
#else
# define LZMA_API_EXPORT
#endif
#define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL
#include "lzma.h"
// These allow helping the compiler in some often-executed branches, whose
// result is almost always the same.
#ifdef __GNUC__
# define likely(expr) __builtin_expect(expr, true)
# define unlikely(expr) __builtin_expect(expr, false)
#else
# define likely(expr) (expr)
# define unlikely(expr) (expr)
#endif
/// Size of temporary buffers needed in some filters
#define LZMA_BUFFER_SIZE 4096
/// Starting value for memory usage estimates. Instead of calculating size
/// of _every_ structure and taking into account malloc() overhead etc., we
/// add a base size to all memory usage estimates. It's not very accurate
/// but should be easily good enough.
#define LZMA_MEMUSAGE_BASE (UINT64_C(1) << 15)
/// Start of internal Filter ID space. These IDs must never be used
/// in Streams.
#define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62)
/// Supported flags that can be passed to lzma_stream_decoder()
/// or lzma_auto_decoder().
#define LZMA_SUPPORTED_FLAGS \
( LZMA_TELL_NO_CHECK \
| LZMA_TELL_UNSUPPORTED_CHECK \
| LZMA_TELL_ANY_CHECK \
| LZMA_CONCATENATED )
/// Type of encoder/decoder specific data; the actual structure is defined
/// differently in different coders.
typedef struct lzma_coder_s lzma_coder;
typedef struct lzma_next_coder_s lzma_next_coder;
typedef struct lzma_filter_info_s lzma_filter_info;
/// Type of a function used to initialize a filter encoder or decoder
typedef lzma_ret (*lzma_init_function)(
lzma_next_coder *next, lzma_allocator *allocator,
const lzma_filter_info *filters);
/// Type of a function to do some kind of coding work (filters, Stream,
/// Block encoders/decoders etc.). Some special coders use don't use both
/// input and output buffers, but for simplicity they still use this same
/// function prototype.
typedef lzma_ret (*lzma_code_function)(
lzma_coder *coder, lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size,
lzma_action action);
/// Type of a function to free the memory allocated for the coder
typedef void (*lzma_end_function)(
lzma_coder *coder, lzma_allocator *allocator);
/// Raw coder validates and converts an array of lzma_filter structures to
/// an array of lzma_filter_info structures. This array is used with
/// lzma_next_filter_init to initialize the filter chain.
struct lzma_filter_info_s {
/// Filter ID. This is used only by the encoder
/// with lzma_filters_update().
lzma_vli id;
/// Pointer to function used to initialize the filter.
/// This is NULL to indicate end of array.
lzma_init_function init;
/// Pointer to filter's options structure
void *options;
};
/// Hold data and function pointers of the next filter in the chain.
struct lzma_next_coder_s {
/// Pointer to coder-specific data
lzma_coder *coder;
/// Filter ID. This is LZMA_VLI_UNKNOWN when this structure doesn't
/// point to a filter coder.
lzma_vli id;
/// "Pointer" to init function. This is never called here.
/// We need only to detect if we are initializing a coder
/// that was allocated earlier. See lzma_next_coder_init and
/// lzma_next_strm_init macros in this file.
uintptr_t init;
/// Pointer to function to do the actual coding
lzma_code_function code;
/// Pointer to function to free lzma_next_coder.coder. This can
/// be NULL; in that case, lzma_free is called to free
/// lzma_next_coder.coder.
lzma_end_function end;
/// Pointer to function to return the type of the integrity check.
/// Most coders won't support this.
lzma_check (*get_check)(const lzma_coder *coder);
/// Pointer to function to get and/or change the memory usage limit.
/// If new_memlimit == 0, the limit is not changed.
lzma_ret (*memconfig)(lzma_coder *coder, uint64_t *memusage,
uint64_t *old_memlimit, uint64_t new_memlimit);
/// Update the filter-specific options or the whole filter chain
/// in the encoder.
lzma_ret (*update)(lzma_coder *coder, lzma_allocator *allocator,
const lzma_filter *filters,
const lzma_filter *reversed_filters);
};
/// Macro to initialize lzma_next_coder structure
#define LZMA_NEXT_CODER_INIT \
(lzma_next_coder){ \
.coder = NULL, \
.init = (uintptr_t)(NULL), \
.id = LZMA_VLI_UNKNOWN, \
.code = NULL, \
.end = NULL, \
.get_check = NULL, \
.memconfig = NULL, \
.update = NULL, \
}
/// Internal data for lzma_strm_init, lzma_code, and lzma_end. A pointer to
/// this is stored in lzma_stream.
struct lzma_internal_s {
/// The actual coder that should do something useful
lzma_next_coder next;
/// Track the state of the coder. This is used to validate arguments
/// so that the actual coders can rely on e.g. that LZMA_SYNC_FLUSH
/// is used on every call to lzma_code until next.code has returned
/// LZMA_STREAM_END.
enum {
ISEQ_RUN,
ISEQ_SYNC_FLUSH,
ISEQ_FULL_FLUSH,
ISEQ_FINISH,
ISEQ_END,
ISEQ_ERROR,
} sequence;
/// A copy of lzma_stream avail_in. This is used to verify that the
/// amount of input doesn't change once e.g. LZMA_FINISH has been
/// used.
size_t avail_in;
/// Indicates which lzma_action values are allowed by next.code.
bool supported_actions[4];
/// If true, lzma_code will return LZMA_BUF_ERROR if no progress was
/// made (no input consumed and no output produced by next.code).
bool allow_buf_error;
};
/// Allocates memory
extern void *lzma_alloc(size_t size, lzma_allocator *allocator)
lzma_attribute((__malloc__)) lzma_attr_alloc_size(1);
/// Frees memory
extern void lzma_free(void *ptr, lzma_allocator *allocator);
/// Allocates strm->internal if it is NULL, and initializes *strm and
/// strm->internal. This function is only called via lzma_next_strm_init macro.
extern lzma_ret lzma_strm_init(lzma_stream *strm);
/// Initializes the next filter in the chain, if any. This takes care of
/// freeing the memory of previously initialized filter if it is different
/// than the filter being initialized now. This way the actual filter
/// initialization functions don't need to use lzma_next_coder_init macro.
extern lzma_ret lzma_next_filter_init(lzma_next_coder *next,
lzma_allocator *allocator, const lzma_filter_info *filters);
/// Update the next filter in the chain, if any. This checks that
/// the application is not trying to change the Filter IDs.
extern lzma_ret lzma_next_filter_update(
lzma_next_coder *next, lzma_allocator *allocator,
const lzma_filter *reversed_filters);
/// Frees the memory allocated for next->coder either using next->end or,
/// if next->end is NULL, using lzma_free.
extern void lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator);
/// Copy as much data as possible from in[] to out[] and update *in_pos
/// and *out_pos accordingly. Returns the number of bytes copied.
extern size_t lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size);
/// \brief Return if expression doesn't evaluate to LZMA_OK
///
/// There are several situations where we want to return immediately
/// with the value of expr if it isn't LZMA_OK. This macro shortens
/// the code a little.
#define return_if_error(expr) \
do { \
const lzma_ret ret_ = (expr); \
if (ret_ != LZMA_OK) \
return ret_; \
} while (0)
/// If next isn't already initialized, free the previous coder. Then mark
/// that next is _possibly_ initialized for the coder using this macro.
/// "Possibly" means that if e.g. allocation of next->coder fails, the
/// structure isn't actually initialized for this coder, but leaving
/// next->init to func is still OK.
#define lzma_next_coder_init(func, next, allocator) \
do { \
if ((uintptr_t)(func) != (next)->init) \
lzma_next_end(next, allocator); \
(next)->init = (uintptr_t)(func); \
} while (0)
/// Initializes lzma_strm and calls func() to initialize strm->internal->next.
/// (The function being called will use lzma_next_coder_init()). If
/// initialization fails, memory that wasn't freed by func() is freed
/// along strm->internal.
#define lzma_next_strm_init(func, strm, ...) \
do { \
return_if_error(lzma_strm_init(strm)); \
const lzma_ret ret_ = func(&(strm)->internal->next, \
(strm)->allocator, __VA_ARGS__); \
if (ret_ != LZMA_OK) { \
lzma_end(strm); \
return ret_; \
} \
} while (0)
#endif

View File

@@ -1,29 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file easy_decoder_memusage.c
/// \brief Decoder memory usage calculation to match easy encoder presets
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "easy_preset.h"
extern LZMA_API(uint64_t)
lzma_easy_decoder_memusage(uint32_t preset)
{
lzma_options_easy opt_easy;
if (lzma_easy_preset(&opt_easy, preset))
return UINT32_MAX;
return lzma_raw_decoder_memusage(opt_easy.filters);
}

View File

@@ -1,32 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file easy_preset.c
/// \brief Preset handling for easy encoder and decoder
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "easy_preset.h"
extern bool
lzma_easy_preset(lzma_options_easy *opt_easy, uint32_t preset)
{
if (lzma_lzma_preset(&opt_easy->opt_lzma, preset))
return true;
opt_easy->filters[0].id = LZMA_FILTER_LZMA2;
opt_easy->filters[0].options = &opt_easy->opt_lzma;
opt_easy->filters[1].id = LZMA_VLI_UNKNOWN;
return false;
}

View File

@@ -1,37 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file easy_preset.h
/// \brief Preset handling for easy encoder and decoder
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "common.h"
typedef struct {
/// We need to keep the filters array available in case
/// LZMA_FULL_FLUSH is used.
lzma_filter filters[LZMA_FILTERS_MAX + 1];
/// Options for LZMA2
lzma_options_lzma opt_lzma;
// Options for more filters can be added later, so this struct
// is not ready to be put into the public API.
} lzma_options_easy;
/// Set *easy to the settings given by the preset. Returns true on error,
/// false on success.
extern bool lzma_easy_preset(lzma_options_easy *easy, uint32_t preset);

View File

@@ -1,92 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file filter_buffer_decoder.c
/// \brief Single-call raw decoding
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "filter_decoder.h"
extern LZMA_API(lzma_ret)
lzma_raw_buffer_decode(const lzma_filter *filters, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos, size_t in_size,
uint8_t *out, size_t *out_pos, size_t out_size)
{
// Validate what isn't validated later in filter_common.c.
if (in == NULL || in_pos == NULL || *in_pos > in_size || out == NULL
|| out_pos == NULL || *out_pos > out_size)
return LZMA_PROG_ERROR;
// Initialize the decoer.
lzma_next_coder next = LZMA_NEXT_CODER_INIT;
return_if_error(lzma_raw_decoder_init(&next, allocator, filters));
// Store the positions so that we can restore them if something
// goes wrong.
const size_t in_start = *in_pos;
const size_t out_start = *out_pos;
// Do the actual decoding and free decoder's memory.
lzma_ret ret = next.code(next.coder, allocator, in, in_pos, in_size,
out, out_pos, out_size, LZMA_FINISH);
if (ret == LZMA_STREAM_END) {
ret = LZMA_OK;
} else {
if (ret == LZMA_OK) {
// Either the input was truncated or the
// output buffer was too small.
assert(*in_pos == in_size || *out_pos == out_size);
if (*in_pos != in_size) {
// Since input wasn't consumed completely,
// the output buffer became full and is
// too small.
ret = LZMA_BUF_ERROR;
} else if (*out_pos != out_size) {
// Since output didn't became full, the input
// has to be truncated.
ret = LZMA_DATA_ERROR;
} else {
// All the input was consumed and output
// buffer is full. Now we don't immediately
// know the reason for the error. Try
// decoding one more byte. If it succeeds,
// then the output buffer was too small. If
// we cannot get a new output byte, the input
// is truncated.
uint8_t tmp[1];
size_t tmp_pos = 0;
(void)next.code(next.coder, allocator,
in, in_pos, in_size,
tmp, &tmp_pos, 1, LZMA_FINISH);
if (tmp_pos == 1)
ret = LZMA_BUF_ERROR;
else
ret = LZMA_DATA_ERROR;
}
}
// Restore the positions.
*in_pos = in_start;
*out_pos = out_start;
}
lzma_next_end(&next, allocator);
return ret;
}

View File

@@ -1,354 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file filter_common.c
/// \brief Filter-specific stuff common for both encoder and decoder
//
//
// Copyright 2012 Lasse Collin
// Public Domain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "filter_common.h"
static const struct {
/// Filter ID
lzma_vli id;
/// Size of the filter-specific options structure
size_t options_size;
/// True if it is OK to use this filter as non-last filter in
/// the chain.
bool non_last_ok;
/// True if it is OK to use this filter as the last filter in
/// the chain.
bool last_ok;
/// True if the filter may change the size of the data (that is, the
/// amount of encoded output can be different than the amount of
/// uncompressed input).
bool changes_size;
} features[] = {
#if defined (HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1)
{
.id = LZMA_FILTER_LZMA1,
.options_size = sizeof(lzma_options_lzma),
.non_last_ok = false,
.last_ok = true,
.changes_size = true,
},
#endif
#if defined(HAVE_ENCODER_LZMA2) || defined(HAVE_DECODER_LZMA2)
{
.id = LZMA_FILTER_LZMA2,
.options_size = sizeof(lzma_options_lzma),
.non_last_ok = false,
.last_ok = true,
.changes_size = true,
},
#endif
#if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86)
{
.id = LZMA_FILTER_X86,
.options_size = sizeof(lzma_options_bcj),
.non_last_ok = true,
.last_ok = false,
.changes_size = false,
},
#endif
#if defined(HAVE_ENCODER_POWERPC) || defined(HAVE_DECODER_POWERPC)
{
.id = LZMA_FILTER_POWERPC,
.options_size = sizeof(lzma_options_bcj),
.non_last_ok = true,
.last_ok = false,
.changes_size = false,
},
#endif
#if defined(HAVE_ENCODER_IA64) || defined(HAVE_DECODER_IA64)
{
.id = LZMA_FILTER_IA64,
.options_size = sizeof(lzma_options_bcj),
.non_last_ok = true,
.last_ok = false,
.changes_size = false,
},
#endif
#if defined(HAVE_ENCODER_ARM) || defined(HAVE_DECODER_ARM)
{
.id = LZMA_FILTER_ARM,
.options_size = sizeof(lzma_options_bcj),
.non_last_ok = true,
.last_ok = false,
.changes_size = false,
},
#endif
#if defined(HAVE_ENCODER_ARMTHUMB) || defined(HAVE_DECODER_ARMTHUMB)
{
.id = LZMA_FILTER_ARMTHUMB,
.options_size = sizeof(lzma_options_bcj),
.non_last_ok = true,
.last_ok = false,
.changes_size = false,
},
#endif
#if defined(HAVE_ENCODER_SPARC) || defined(HAVE_DECODER_SPARC)
{
.id = LZMA_FILTER_SPARC,
.options_size = sizeof(lzma_options_bcj),
.non_last_ok = true,
.last_ok = false,
.changes_size = false,
},
#endif
#if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
{
.id = LZMA_FILTER_DELTA,
.options_size = sizeof(lzma_options_delta),
.non_last_ok = true,
.last_ok = false,
.changes_size = false,
},
#endif
{
.id = LZMA_VLI_UNKNOWN
}
};
extern LZMA_API(lzma_ret)
lzma_filters_copy(const lzma_filter *src, lzma_filter *dest,
lzma_allocator *allocator)
{
if (src == NULL || dest == NULL)
return LZMA_PROG_ERROR;
lzma_ret ret;
size_t i;
for (i = 0; src[i].id != LZMA_VLI_UNKNOWN; ++i) {
// There must be a maximum of four filters plus
// the array terminator.
if (i == LZMA_FILTERS_MAX) {
ret = LZMA_OPTIONS_ERROR;
goto error;
}
dest[i].id = src[i].id;
if (src[i].options == NULL) {
dest[i].options = NULL;
} else {
// See if the filter is supported only when the
// options is not NULL. This might be convenient
// sometimes if the app is actually copying only
// a partial filter chain with a place holder ID.
//
// When options is not NULL, the Filter ID must be
// supported by us, because otherwise we don't know
// how big the options are.
size_t j;
for (j = 0; src[i].id != features[j].id; ++j) {
if (features[j].id == LZMA_VLI_UNKNOWN) {
ret = LZMA_OPTIONS_ERROR;
goto error;
}
}
// Allocate and copy the options.
dest[i].options = lzma_alloc(features[j].options_size,
allocator);
if (dest[i].options == NULL) {
ret = LZMA_MEM_ERROR;
goto error;
}
memcpy(dest[i].options, src[i].options,
features[j].options_size);
}
}
// Terminate the filter array.
assert(i <= LZMA_FILTERS_MAX + 1);
dest[i].id = LZMA_VLI_UNKNOWN;
dest[i].options = NULL;
return LZMA_OK;
error:
// Free the options which we have already allocated.
while (i-- > 0) {
lzma_free(dest[i].options, allocator);
dest[i].options = NULL;
}
return ret;
}
static lzma_ret
validate_chain(const lzma_filter *filters, size_t *count)
{
// There must be at least one filter.
if (filters == NULL || filters[0].id == LZMA_VLI_UNKNOWN)
return LZMA_PROG_ERROR;
// Number of non-last filters that may change the size of the data
// significantly (that is, more than 1-2 % or so).
size_t changes_size_count = 0;
// True if it is OK to add a new filter after the current filter.
bool non_last_ok = true;
// True if the last filter in the given chain is actually usable as
// the last filter. Only filters that support embedding End of Payload
// Marker can be used as the last filter in the chain.
bool last_ok = false;
size_t i = 0;
do {
size_t j;
for (j = 0; filters[i].id != features[j].id; ++j)
if (features[j].id == LZMA_VLI_UNKNOWN)
return LZMA_OPTIONS_ERROR;
// If the previous filter in the chain cannot be a non-last
// filter, the chain is invalid.
if (!non_last_ok)
return LZMA_OPTIONS_ERROR;
non_last_ok = features[j].non_last_ok;
last_ok = features[j].last_ok;
changes_size_count += features[j].changes_size;
} while (filters[++i].id != LZMA_VLI_UNKNOWN);
// There must be 1-4 filters. The last filter must be usable as
// the last filter in the chain. A maximum of three filters are
// allowed to change the size of the data.
if (i > LZMA_FILTERS_MAX || !last_ok || changes_size_count > 3)
return LZMA_OPTIONS_ERROR;
*count = i;
return LZMA_OK;
}
extern lzma_ret
lzma_raw_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
const lzma_filter *options,
lzma_filter_find coder_find, bool is_encoder)
{
// Do some basic validation and get the number of filters.
size_t count;
return_if_error(validate_chain(options, &count));
// Set the filter functions and copy the options pointer.
lzma_filter_info filters[LZMA_FILTERS_MAX + 1];
#if __MOJOSETUP__
size_t i;
#endif
if (is_encoder) {
#if __MOJOSETUP__
for (i = 0; i < count; ++i) {
#else
for (size_t i = 0; i < count; ++i) {
#endif
// The order of the filters is reversed in the
// encoder. It allows more efficient handling
// of the uncompressed data.
const size_t j = count - i - 1;
const lzma_filter_coder *const fc
= coder_find(options[i].id);
if (fc == NULL || fc->init == NULL)
return LZMA_OPTIONS_ERROR;
filters[j].id = options[i].id;
filters[j].init = fc->init;
filters[j].options = options[i].options;
}
} else {
#if __MOJOSETUP__
for (i = 0; i < count; ++i) {
#else
for (size_t i = 0; i < count; ++i) {
#endif
const lzma_filter_coder *const fc
= coder_find(options[i].id);
if (fc == NULL || fc->init == NULL)
return LZMA_OPTIONS_ERROR;
filters[i].id = options[i].id;
filters[i].init = fc->init;
filters[i].options = options[i].options;
}
}
// Terminate the array.
filters[count].id = LZMA_VLI_UNKNOWN;
filters[count].init = NULL;
// Initialize the filters.
const lzma_ret ret = lzma_next_filter_init(next, allocator, filters);
if (ret != LZMA_OK)
lzma_next_end(next, allocator);
return ret;
}
extern uint64_t
lzma_raw_coder_memusage(lzma_filter_find coder_find,
const lzma_filter *filters)
{
// The chain has to have at least one filter.
{
size_t tmp;
if (validate_chain(filters, &tmp) != LZMA_OK)
return UINT64_MAX;
}
uint64_t total = 0;
size_t i = 0;
do {
const lzma_filter_coder *const fc
= coder_find(filters[i].id);
if (fc == NULL)
return UINT64_MAX; // Unsupported Filter ID
if (fc->memusage == NULL) {
// This filter doesn't have a function to calculate
// the memory usage and validate the options. Such
// filters need only little memory, so we use 1 KiB
// as a good estimate. They also accept all possible
// options, so there's no need to worry about lack
// of validation.
total += 1024;
} else {
// Call the filter-specific memory usage calculation
// function.
const uint64_t usage
= fc->memusage(filters[i].options);
if (usage == UINT64_MAX)
return UINT64_MAX; // Invalid options
total += usage;
}
} while (filters[++i].id != LZMA_VLI_UNKNOWN);
// Add some fixed amount of extra. It's to compensate memory usage
// of Stream, Block etc. coders, malloc() overhead, stack etc.
return total + LZMA_MEMUSAGE_BASE;
}

Some files were not shown because too many files have changed in this diff Show More